How to prevent browser page caching in Rails

Ubuntu → Apache → Phusion Passenger → Rails 2.3.

The main part of my site reacts to your clicks. So, if you click on a link, it will send you on to the destination, and instantly regenerate your page.

But, if you hit the back button, you don't see the new page. Unfortunately, it's not showing up without a manual refresh; it appears the browser is caching it. I want to make sure the browser does not cache the page.

Separately, I do want to set far-future expiration dates for all my static assets.

What's the best way to solve this? Should I solve this in Ruby on Rails? Apache? JavaScript?


Alas. Neither of these suggestions forced the behavior I'm looking for.

Maybe there's a JavaScript answer? I could have Ruby on Rails write out a timestamp in a comment, and then have the JavaScript code check to see if the times are within five seconds (or whatever works). If yes, then fine, but if no, then reload the page?

Do you think this would work?

69907 次浏览

我在控制器中使用这一行取得了一些成功。它可以在 Safari 和 Internet Explorer 中使用,但我还没见过它在火狐中使用。

response.headers["Expires"] = "#{1.year.ago}"

第二点,如果您使用 Ruby on Rails 的 helper 方法,比如

stylesheet_link_tag

并将默认设置保留在 Web 服务器上,这些资产通常缓存得很好。

我终于弄明白了这一点-http://blog.serendeputy.com/posts/how-to-prevent-browsers-from-caching-a-page-in-rails/application_controller.rb

Ruby on Rails5之后:

class ApplicationController < ActionController::Base


before_action :set_cache_headers


private


def set_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Mon, 01 Jan 1990 00:00:00 GMT"
end
end

RubyonRails 4及其旧版本:

class ApplicationController < ActionController::Base


before_filter :set_cache_headers


private


def set_cache_headers
response.headers["Cache-Control"] = "no-cache, no-store"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Mon, 01 Jan 1990 00:00:00 GMT"
end
end

更简洁的方法是编写 Rack 中间件,它根据一些逻辑(例如,只针对 application/xml mime-type)更改 Cache-Control 报头。

或者,对于一种更丑陋但仍然可行的方法,可以将 Response: : DEFAULT _ CACHE _ CONTROL ActionDispatch: : Response: : DEFAULT _ CACHE _ CONTROL常量更改为“ no-cache”。

当然,如果需要控制器和/或操作粒度,那么最好在控制器中执行此操作。

用途:

expires_now()

Expires _ now ()

注意: 您不能有条件地清除缓存(如果 before_filter只调用 reset_cache,如果用户已经在那里)。您需要清除高速缓存,因为浏览器不会发出新的请求,只是为了查看这次是否需要重新加载,即使上次不需要。

例如:

before_filter :reset_cache, if: :user_completed_demographics?

不会阻止用户返回,因为浏览器使用 Back按钮上的原始缓存头。

before_filter :reset_cache

然而,将工作(刷新页面和清除缓存之前,您添加了这一点,显然) ,因为,在第一个请求,浏览器将获得 no-cache, no-store, ...,并将其应用到未来的页面加载。

no_cache_control宝石。

如果你需要对所有的响应都这样做,例如,传递一个 渗透测试(打嗝套房,Detectify,等等) ,你可以在 Ruby on Rails 4 + 上安装这个 Gem,以便为所有的响应添加以下头文件:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: -1

它的工作原理就像一个魔咒,是真正的正确方式去安全,HTTPS 网络应用程序,需要身份验证,以做任何事情。