问题 使用Sinatra时,如何控制静态资产的缓存? [关闭]


我正在使用最新的Sinatra,我正在Heroku上主持。有没有办法可以为我提供的静态资产设置缓存标头 /public 目录?

Sinatra提供来自的文件 /public 检查任何已定义的路由之前的目录,所以我不能只是 cache_control 路线内的方法。

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


6707
2017-10-10 18:32


起源

你能更清楚地解释一下为什么要这样做吗?你想要完成什么? - the Tin Man
埃姆。我正在提供不会发生很大变化的CSS和JavaScript,因此我不希望浏览器每次都加载文件,而是在我上传新版本之前对其进行缓存。 - js-coder
你能更好地定义“它不起作用”吗? - the Tin Man
当我检查标题时,他们说 max_age:0。 - js-coder
所以这个问题已经结束,因为在成功回答之后它无法“合理地回答”。 o.0 - js-coder


答案:


你可以使用 static_cache_control 设置 设置 Cache-Control Sinatra提供的静态文件的标头:

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

请注意,您需要使用显式数组 [...]

这也适用于中的所有文件 public 目录,即您不能为css和javascript文件指定不同的标头。

(如果你是  使用Heroku并使用Apache或Nginx来提供静态文件然后这将无法工作,在这种情况下,您需要单独配置您的网络服务器)。


13
2017-10-10 21:51



谢谢,这完美无缺。 :)它也适用于本地,因为我也在那里使用机架,我想。只是最后一个问题:当我更改文件时,是否会自动加载新文件,或者我是否需要通过附加一些url参数来触发它(如 ?#{File.mtime(filename)})? - js-coder
@dotweb不,新文件不会自动加载(这几乎是缓存的重点,浏览器甚至不会要求它,所以它无法知道它已经过时了)。您需要为文件使用某种url param或版本名称。 - matt
是的,我只是不确定服务器是否已经有某种方法告诉浏览器在检测到新版本时重新刷新缓存。无论如何,我只会使用url params,谢谢你的帮助。 :) - js-coder


我用以下方法创建了一个简单的Sinatra网站:

#!/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)。


1
2017-10-10 19:38



哦,也许我没有详细解释它。在我的应用程序的/ public文件夹(不是/ public url)中,是可以直接查看的所有文件(可以在/app.js访问文件/public/app.js而无需添加到Ruby代码的路径。)我希望缓存这些文件。现在我看到我尝试的并没有做我真正想要的事情。 - js-coder