【问题标题】:Caching with Rails app and Chrome Browser使用 Rails 应用程序和 Chrome 浏览器进行缓存
【发布时间】:2017-04-13 16:35:05
【问题描述】:

我希望应用程序响应代码 304 而不是 200。 但即使 IF-NONE-MATCH 等于 ETAG 它也不会发生。

我使用 'Cache-Control: no-cache' 来不将响应存储在缓存中以进行每次验证。否则 Chrome 会使用它的磁盘缓存,这是不可接受的。

请求:

GET /api/v4/record/11728 HTTP/1.1
Host: host.domain.com
Connection: keep-alive
Authorization: Basic YWRtaW467Uc2Zs0eTIwMTM=
Origin: https://host.domain.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
Accept: application/json, text/plain, */*
DNT: 1
Referer: https://host-ui.domain.com/some_page
Accept-Encoding: gzip, deflate, sdch, br
If-None-Match: W/"39dcd8467e47701a69c617333f7b6dac"
If-Modified-Since: Thu, 13 Apr 2017 16:09:25 GMT
Name

回应:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,PATCH,HEAD,OPTIONS
Access-Control-Allow-Origin: https://host-ui.domain.com
Cache-Control: no-cache
Content-Encoding: gzip
Content-Type: application/json; charset=utf-8
Date: Thu, 13 Apr 2017 16:20:31 GMT
ETag: W/"39dcd8467e47701a69c617333f7b6dac"
Last-Modified: Thu, 13 Apr 2017 16:09:25 GMT
Server: nginx/1.8.1 + Phusion Passenger 4.0.60
Status: 200 OK
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Powered-By: Phusion Passenger 4.0.60
X-Request-Id: ab87433e-62bd-437f-ad7c-0e1d3f95257b
X-Runtime: 0.209121
X-XSS-Protection: 1; mode=block
transfer-encoding: chunked
Connection: keep-alive

在应用程序中常见的动作如下:

  def action

    record = Model.find(params['id'])

    if stale?(record)
      hard_work_result = to_do_somethig
      render json: {
          success: 0,
          result: hard_work_result
      }
    end
  end

【问题讨论】:

  • 您能否检查If-None-Match HTTP 标头实际上可用于控制器操作? MiniProfiler 等代理和中间件可能会删除缓存相关的 HTTP 标头。检查Rails caching: stale? always returns true in development 和Reading header data in rails 讨论。
  • 是的,它可用。而且我在开发模式下具有正确的行为。当然 MiniRackProfiler 也被禁用了。
  • 你使用哪个版本的 Rails 框架?
  • 它是rails 4.2.8。看标签

标签: google-chrome ruby-on-rails-4 browser-cache


【解决方案1】:

这个故事背后似乎有一段历史:gzip 正在搞乱弱 ETags
弱ETag:ETag: W/"8763458...
强ETag:ETag: "8763458...

如果您使用 cURL 并从 Accept-Encoding 禁用 gzip(或在 chrome 中使用 modheaders:Disable gzip compression in chrome),您可以测试这是问题所在

参考资料:

Getting no 304 response in Chrome/Safari but via curl
https://masa331.github.io/2016/01/06/roda-etag-caching-gotcha.html
Weak ETAGs in Rails?

解决方案?

从 nginx 本身运行时,没有出现问题。上面的第一个链接表明,如果您在 nginx 内部遇到问题,那么在 gzip on; 之后添加一个 etag on; 可以解决问题。具体来说,虽然没有返回弱 etag。如果你想启用 gzip,从 nginx 中运行似乎是唯一的选择。

我的版本

Server: nginx/1.10.2 + Phusion Passenger 5.1.2`)

ii  ruby-rails                      2:4.2.6-1
ii  ruby2.3                         2.3.1-2~16.04

通过编辑 nginx.conf.erb 并禁用 gzip,我设法在乘客独立运行时解决了该问题。为此,首先需要获取conf文件的模板:

passenger start --debug-nginx-config

这将在您的当前目录中放置一个名为 nginx.conf.erb 的文件。然后你可以编辑这个文件说:

gzip off;

然后用这个文件重新启动乘客

passenger start --nginx-config-template nginx.conf.erb

see here了解下载和使用nginx.conf.erb的详细信息

在任何一种情况下,您都应该能够看到没有返回弱 etags

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 2011-08-18
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 2011-07-25
    • 2018-09-29
    相关资源
    最近更新 更多