这篇博客是我们 《Rails 5 系列文章》 中的一篇
让我们先来看看 Rails 4.2.4 应用默认的响应头是如何的:
现在,假设我们要设置一个自定义的相应头。很容易,我们只需要在 controller 中添加以下代码:
response.headers['X-Tracking-ID'] = '123456'
于是我们看到了自定义的头:
现在我们需要不仅能对标准 Web 请求设置自定义响应头,而且对静态资源也需要设置。举例来说被本地 Rails 服务跑着的 application.js
文件。这里该如何设置呢?
实际上在 Rails 4 中是不可能的,它唯一可以为静态资源的响应头做的设置项只有:Cache-Control
,如下:
# 在 config/environments/production.rb 加入如下代码行
config.static_cache_control = 'public, max-age=1000'
这时我们就为资源文件设置了 Cache-Control
的值:
除此以外的任何响应头都不行,那是一个限制。
Rails 跑静态资源文件并非强项。那是 Apache 和 Nginx 的拿手好戏。因此,在实际生产环境中,几乎所有人都会在 Rails Server 之前架一道 Apache 或 Nginx 以至于无需用 Rails 来跑静态资源。
Havig 说,Rails 应用跑在 Heroku 上是个异常。跑在 Heroku 上的 Rails 应用的资源文件其实被 Rails 应用自己在跑着。
我们的 网站 是跑在 Heroku 上的。当我们用 Google page speed insights 跑一遍网站,就被警告说我们没有为资源文件设置 Expires
头。
下图显示了 application.js
的头
现在你就了解了我们遇到的问题。
Expires
Cache-Control
一种方案就是将网站放到 Digital Ocean 上在使用 Apache 或者 Nginx。
如今 Rails 整合了头访问控制的基础支持 并且加入了自定义 HTTP 头的能力。
场景背后,Rails 使用 ActionDispatch::Static
中间件来运行静态文件。例如,一个取图片的请求,在请求周期中通过 ActionDispatch::Static
。ActionDispatch::Static
从响应中带有适当头的服务中运行 Rack:File
对象。被运行的图片就能拥有类似 Content-Type
,Cache-Control
等头。
为了修复该问题,我们使用了最新的 Rails
gem 'rails', github: 'rails/rails'
gem 'rack', github: 'rack/rack' # Rails depends on Rack 2
gem 'arel', github: 'rails/arel' # Rails master works alongside of arel master.
接着,我们修改配置来提供缺失的 Expires
头
# production.rb
config.public_file_server.headers = {
'Cache-Control' => 'public, s-maxage=31536000, maxage=15552000',
'Expires' => "#{1.year.from_now.to_formatted_s(:rfc822)}"
}
这里,我们先设置了 Cache-Control
头来使用公共缓存,maxage
和 s-maxage
均设为一年(31536000 秒)。
然后设置缺失的 Expires
值,之后我们再次测试就能看到新的头,再没有收到头缺失的警告。
这是改变后的静态文件响应头:
为更好地使用和了解关于不同头对静态文件的使用细节,敬请参考 RFC2616
作者 Vipul 于 2015.10.31