使用 Sinatra 提供静态文件

Posted

技术标签:

【中文标题】使用 Sinatra 提供静态文件【英文标题】:Serving static files with Sinatra 【发布时间】:2011-01-27 02:24:57 【问题描述】:

我有一个仅使用 html、CSS 和 javascript 的页面网站。我想将应用程序部署到 Heroku,但找不到方法。我现在正在尝试使该应用程序与 Sinatra 一起使用。

.
|-- application.css
|-- application.js
|-- index.html
|-- jquery.js
`-- myapp.rb

以下是myapp.rb的内容。

require 'rubygems'
require 'sinatra'

get "/" do
  # What should I write here to point to the `index.html`
end

【问题讨论】:

我了解到访问localhost:2345/index.html 有效。 您可以使用 WebBrick 在几行中提供静态文件。 require 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") server.stop ; server.start; 然后运行ruby myapp.rb。删除 Heroku 的端口。将web: ruby myapp.rb 放入您的Procfile。评论不回答,因为它不适用于 Sinatra,但我认为它简化了依赖关系。 【参考方案1】:

您可以使用 send_file 帮助程序来提供文件。

require 'sinatra'

get '/' do
  send_file File.join(settings.public_folder, 'index.html')
end

这将从配置为包含应用程序静态文件的任何目录中提供index.html

【讨论】:

我认为较新的 Sinatra 应用程序使用 set :public_folder,因此您将使用 settings.public_folder 而不是 settings.public 我将答案更新为使用 settings.public_folder。较旧的应用程序可能仍需要使用 settings.public。【参考方案2】:

无需任何额外配置,Sinatra 将提供 public 中的资产。对于空路由,您需要渲染索引文档。

require 'rubygems'
require 'sinatra'

get '/' do
  File.read(File.join('public', 'index.html'))
end

路由应该返回一个String,它成为 HTTP 响应正文。 File.read 打开文件,读取文件,关闭文件并返回String

【讨论】:

你应该做send_file File.expand_path('index.html', settings.public) 这现在是不正确的。您应该将settings.public 替换为settings.public_folder 以获得send_file File.expand_path('index.html', settings.public_folder) @zhirzh send_file,它为你做了额外的事情github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351 File.read 将整个文件读入内存。这可以或不可以,取决于文件的大小和并发请求的数量。 @WayneConrad 相反,send_file 可以吗?还是一样?【参考方案3】:

您可以只从公共文件夹中托管它们,它们不需要路由。

.
-- myapp.rb
`-- public
    |-- application.css
    |-- application.js
    |-- index.html
    `-- jquery.js

在 myapp.rb 中

set :public_folder, 'public'

get "/" do
  redirect '/index.html'
end

链接到公共的一些子文件夹

set :public_folder, 'public'
get "/" do
  redirect '/subfolder/index.html' 
end

./public 中的所有内容都可以从 '/whatever/bla.html 访问

示例: ./public/stylesheets/screen.css 可通过“/stylesheets/screen.css”访问,无需路由

【讨论】:

如果 public 有许多嵌套文件夹(您不想为其创建路由),其中包含您希望默认的 index.html 文件,该怎么办? 我已经扩展了解决方案。我希望它有助于澄清,一切都可以在公共场合访问,不需要路线,只需省略路径的“公共”部分。 在 Heroku 上使用 rackup 我必须使用 set :public_folder, 'public'。这是让它工作的关键,尽管 Sinatra 文档暗示这已经被设置为默认值。【参考方案4】:

请记住,在生产环境中,您可以让 Web 服务器自动发送 index.html,这样请求就不会到达 Sinatra。这对性能来说更好,因为您不必通过 Sinatra/Rack 堆栈来提供静态文本,而这正是 Apache/nginx 擅长的。

【讨论】:

哦,是的,呵呵。那我就用 Erb 用 Varnish 来兑现吧。 如何在生产环境中配置它?我一直在寻找有关与 Sinatra 和 Rack 交叉引用的文档,但找不到。基本上我希望将 index.html 加载到任何 /public 文件夹中,如果用户只放置文件夹名称【参考方案5】:

Sinatra 应该允许您从公共目录 as explained in the docs 提供静态文件:

静态文件

静态文件从 ./public 目录提供。您可以通过设置 :public 选项来指定不同的位置:

请注意,公共目录名称不包含在 URL 中。文件 ./public/css/style.css 以 example.com/css/style.css 的形式提供。

【讨论】:

为什么这个有4票?它没有回答在请求文件夹时如何显示默认文档的问题。【参考方案6】:

在主 rb 文件中添加以下行

set :public_folder, 'public'

参考:http://sinatrarb.com/configuration.html#static---enabledisable-static-file-routes

【讨论】:

【参考方案7】:

http://sinatrarb.com/configuration.html#static---enabledisable-static-file-routes

这才是正确的做法。

set :public_folder, 'public'

我使用了静态设置,因为它的设置会影响 public_folder 的使用。

【讨论】:

【参考方案8】:

你总是可以使用 Rack::Static

https://www.rubydoc.info/gems/rack/Rack/Static

只需在“运行”命令之前将这一行添加到“config.ru”中

use Rack::Static, :urls => [""], :root => 'public', :index => 'index.html'

【讨论】:

【参考方案9】:

sinatra-assetpack gem 提供了一大堆功能。语法很甜:

serve '/js', from: '/app/javascripts'

虽然我仍然对 Rails 资产管道有问题,但我觉得使用 sinatra-assetpack 可以更好地控制 - 但大多数时候它只需要几行代码即可。

【讨论】:

【参考方案10】:

更新答案: 我将以上所有内容都绑定在一起,但没有运气可以加载 css、js....等内容,唯一加载的是 index.html... 其余的都在进行 =>> 404 error

我的解决方案:app 文件夹看起来像这样。

index.rb ==>> Sinatra 代码。

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

def html(view)
  File.read(File.join('public', "#view.to_s.html"))
end

public folder==>> 包含其他所有内容...css、js、等等等等。

user@user-SVE1411EGXB:~/sintra1$ ls
index.rb  public
user@user-SVE1411EGXB:~/sintra1$ find public/
public/
public/index.html
public/about_us.html
public/contact.html
public/fonts
public/fonts/fontawesome-webfont.svg
public/fonts/fontawesome-webfont.ttf
public/img
public/img/drink_ZIDO.jpg
public/js
public/js/bootstrap.min.js
public/js/jquery.min.js
public/js/bootstrap.js
public/carsoul2.html
public/css
public/css/font-awesome-ie7.css
public/css/bootstrap.min.css
public/css/font-awesome.min.css
public/css/bootstrap.css
public/css/font-awesome.css
public/css/style.css
user@user-SVE1411EGXB:~/sintra1$

现在启动服务器,您将能够毫无问题地浏览静态页面。

user@user-SVE1411EGXB:~/sintra1$ ruby index.rb 
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop

【讨论】:

【参考方案11】:
require 'rubygems'
require 'sinatra'

set :public_folder, File.dirname(__FILE__) + '/../client'
#client - it's folder with all your file, including myapp.rb

get "/" do
  File.read('index.html')
end

【讨论】:

【参考方案12】:

您可以考虑将index.html 文件移动到views/index.erb,并定义如下端点:

get '/' do
  erb :index
end

【讨论】:

【参考方案13】:

将文件放在public 文件夹中是有限制的。实际上,当您在根目录中时,'/' 路径可以正常工作,因为浏览器会设置您的 css 文件的相对路径,例如 /css/style.css,而 sinatra 将在 public 目录中查找文件。但是,如果您的位置是 /user/create,那么 Web 浏览器将在 /user/create/css/style.css 中查找您的 css 文件并且会失败。

作为一种解决方法,我添加了以下重定向以正确加载 css 文件:

get %r.*/css/style.css do
    redirect('css/style.css')
end

【讨论】:

【参考方案14】:

这个解决方案怎么样? :

get "/subdirectory/:file" do 
  file = params[:file] + "index.html"
  if File.exists?(params[:file])
    return File.open("subdirectory/" + file)
  else
   return "error"
  end
end

因此,如果您现在导航到(例如)/subdirectory/test/,它将加载 subdirectory/test/index.html

【讨论】:

以上是关于使用 Sinatra 提供静态文件的主要内容,如果未能解决你的问题,请参考以下文章

在一个进程多个数据库连接 sinatra 应用程序中使用啥 ORM?

配置 STATIC_ROOT 时 Django 不提供静态文件

从 django 静态文件提供服务并上传到 heroku 时无法找到反应静态文件

使用 Fossil SCM 提供静态文件

在 Elasticbeanstalk Docker 环境中提供 Django 静态文件

使用 ASP.NET 路由来提供静态文件