2012-10-10 50 views
11

我正在使用最新的Sinatra,并在Heroku上进行托管。有没有一种方法可以为从/public目录服务的静态资产设置缓存标头?如何在使用Sinatra时控制静态资产的缓存?

Sinatra在检查任何已定义的路由之前服务于/public目录中的文件,因此我不能只在路由中使用cache_control方法。

/public目录包含我的应用程序的CSS和JavaScript。我不希望浏览器每次都下载这些文件,因为它们不会经常更改。

+0

你能更清楚地解释一下为什么你要这样做吗?你想要完成什么? –

+0

Ehm。我提供的CSS和JavaScript并没有太大改变,所以我不希望浏览器每次都加载这个文件,而是要缓存它直到我上传一个新版本。 –

+0

你可以定义“它没有工作”更好吗? –

回答

13

可以使用static_cache_control setting设置Cache-Control头由西纳特拉服务的静态文件:

set :static_cache_control, [:public, max_age: 60 * 60 * 24 * 365] 

注意,你需要使用一个明确的阵列[...]

这也适用于public目录中的所有文件,即不能为css和javascript文件指定不同的标头。 (如果你是而不是使用Heroku并且使用Apache或Nginx来提供静态文件,那么这将不起作用,在这种情况下,你需要单独配置你的web服务器)。

+1

谢谢,这个作品完美。 :)它也适用于本地,因为我也在那里使用机架。只是最后一个问题:当我更改文件时,新文件是否会自动加载,还是需要通过追加url参数(如'?#{File.mtime(filename)})'来触发该文件? –

+0

@dotweb不会,新文件不会自动加载(这几乎是缓存的重点,浏览器甚至不会自动加载它,因此无法知道它是过时的)。您需要为文件使用某种URL参数或版本名称。 – matt

+0

是的,我只是不确定服务器是否有办法告诉浏览器在检测到新版本时重新创建缓存。无论如何,我只会使用url params,谢谢你的帮助。 :) –

1

我创建了使用简单的辛纳屈网站:

#!/usr/bin/env ruby 

require 'sinatra' 

get '/public/*' do 
    cache_control :public, max_age: 60 * 60 * 24 * 365 
    'this is public' 
end 

get '/' do 
    'hello world!' 
end 

当我请求 '/',我得到了这些标题:

x-frame-options: sameorigin 
x-xss-protection: 1; mode=block 
Content-Type: text/html;charset=utf-8 
Content-Length: 12 
Connection: keep-alive 
Server: thin 1.5.0 codename Knife 

200 OK 

当我请求 '/public/foo',我得到了这些:

x-frame-options: sameorigin 
x-xss-protection: 1; mode=block 
Content-Type: text/html;charset=utf-8 
Cache-Control: public, max-age=31536000 
Content-Length: 14 
Server: thin 1.5.0 codename Knife 

200 OK 

它正在使用Ruby 1.9.3p194上的当前Sinatra(1.3.3)。

+2

哦,也许我没有详细解释它。在我应用程序的/ public文件夹(不是/ public url)中,是可以直接查看的所有文件(可以在/app.js文件中访问文件/public/app.js,而无需向Ruby代码添加路由)我想要这些文件被缓存。现在我看到我试过的东西没有做到我真正想要的东西。 –

相关问题