使用Sinatra提供静态文件


139

我只有一页网站使用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


您可以使用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的,但是我认为它简化了依赖性。
Chloe

Answers:


131

无需任何其他配置,Sinatra将在中提供资产public。对于空路径,您将要呈现索引文档。

require 'rubygems'
require 'sinatra'

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

路由应返回String,成为HTTP响应主体。File.read打开文件,读取文件,关闭文件并返回String


52
你宁愿做send_file File.expand_path('index.html', settings.public)
Konstantin Haase 2012年

32
现在这是不正确的。此时应更换settings.publicsettings.public_folder获得send_file File.expand_path('index.html', settings.public_folder)
阿利斯泰尔·霍尔特

2
@zhirzh send_file,它为您提供了
iain

1
File.read将整个文件读入内存。取决于文件的大小和并发请求的数量,这是否可以确定。
韦恩·康拉德,2016年

@WayneConrad相反,send_file可以吗?还是行为相同?

169

您可以使用send_file助手来提供文件。

require 'sinatra'

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

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


19
我认为较新的Sinatra应用程序会使用set :public_folder,因此您可以使用,settings.public_folder而不是settings.public
Andrew

4
我更新了答案以使用settings.public_folder。较旧的应用可能仍需要使用settings.public。
乍得·德尚

62

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

.
-- 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'访问,无需路由


1
如果public有很多嵌套文件夹(您不想为其创建路由),而这些文件夹都具有index.html文件,而您想将其作为默认文件夹,该怎么办?
德里克

我已经扩展了解决方案。我希望它有助于弄清楚,一切都可以在公共场所访问,不需要任何路线,而只是忽略了路径的“公共”部分。
Morgan

1
我必须使用Heroku上的架子set :public_folder, 'public'。尽管Sinatra文档暗示这已被设置为默认设置,但这仍是使其工作的关键。
Daniel C

12

请记住,在生产中,您可以让您的Web服务器index.html自动发送出去,这样请求就永远不会到达Sinatra。这对于性能更好,因为您不必仅通过Sinatra / Rack堆栈来提供静态文本,而Apache / Nginx正是这么做的。


哦,是的 我先使用Erb,然后使用Varnish兑现。
ma11hew28 2011年

2
您如何在生产中配置它?我一直在寻找与Sinatra和Rack进行交叉引用的文档,但找不到它。基本上,我希望将index.html加载到任何一个包含公用文件夹的/ public文件夹中(如果用户仅放置文件夹名称)

12

Sinatra应该允许您按照docs中的说明从公共目录提供静态文件:

静态文件

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

请注意,URL中不包含公用目录名称。文件./public/css/style.css可作为example.com/css/style.css使用。


4
为什么有4票?它没有回答请求文件夹时如何显示默认文档的问题。
德里克


2

西纳特拉-assetpack宝石提供了一大堆的功能。语法很不错:

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

虽然我仍然对Rails资产管道有问题,但我感觉我可以使用sinatra-assetpack进行更多控制-但大多数情况下,它只需要使用几行代码即可。


2

更新后的答案:我把上面所有的东西都绑在一起,没有运气来加载css,js .... etc内容,唯一要加载的是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

2
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


1

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

get '/' do
  erb :index
end

0

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

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

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


-7

那这个解决方案呢?:

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.