使用 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 时无法找到反应静态文件