Railsでブラウザーページのキャッシュを防ぐ方法


151

Ubuntu-> Apache-> Phusion Passenger-> Rails 2.3

私のサイトの主要部分はあなたのクリックに反応します。したがって、リンクをクリックすると、リンク先に移動し、すぐにページが再生成されます。

ただし、[戻る]ボタンをクリックした場合、新しいページは表示されません。残念ながら、手動で更新しないと表示されません。ブラウザがキャッシュしているようです。ブラウザがページをキャッシュしないようにしたいのですが。

それとは別に、すべての静的アセットに将来の有効期限を設定たいと思います。

これを解決する最良の方法は何ですか?これをRailsで解決する必要がありますか?アパッチ?JavaScript?

助けてくれてありがとう、ジェイソン


ああ。これらの提案はどちらも、私が探している動作を強制するものではありませんでした。

たぶんJavaScriptの答えがありますか?私はレールにコメントのタイムスタンプを書き込んでから、JavaScriptチェックを実行して、時間が5秒以内かどうかを確認することもできます(または何でも機能します)。はいの場合は問題ありませんが、いいえの場合はページをリロードしますか?

これでうまくいくと思いますか?

あなたのすべての協力に感謝します、

ジェイソン

回答:


335

最後にこれを理解しました-http://blog.serendeputy.com/posts/how-to-prevent-browsers-from-caching-a-page-in-rails/ inapplication_controller.rb

Rails 5の後:

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

Rails 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

3
これは「if request.xhr」でラップする必要がありますか?だからそれはajaxの更新でのみ設定されますが、通常のページは設定されませんか?
MintDeparture 2012

3
Cache-Control: no-storeブラウザがHTTP 1.1に準拠している場合にのみ、本当に必要です。セクション14.9.2キャッシュに格納できるもの
gaqzi

28
1990年1月1日は月曜日でした。
Jan Hettich、2014年

2
それは私にとっては機能しません。application_controller.rbに同じコードを追加しました。ログアウトした後、戻るボタンで最後のページを表示できます。どこが間違っているのか教えてください。
トーリン、2015年

1
これはJSとCSSをrailsアプリにキャッシュしませんか?JSとCSSはリクエストごとにサーバーから読み込まれますか?
furiabhavesh 2015

14

3
expires_nowno-cacheヘッダーのみを送信します。ブラウザによっては、これでは不十分な場合があります。(たとえば、Firefoxはno-storeHTTPS以外の接続にを必要としています:developer.mozilla.org/en/docs/Using_Firefox_1.5_caching
Daniel Rikowski

1
これは有効なソリューションではなく、Rails 5.2とChrome 77でテストされましたno-store。また、必要です。
AndrewSouthpaw

3

私はこのラインを使用して、コントローラーである程度成功しました。SafariとInternet Explorerで動作しますが、Firefoxで動作することはありません。

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

2番目のポイントとして、レールヘルパーメソッドを使用する場合

stylesheet_link_tag

Webサーバーのデフォルト設定をそのままにしておくと、アセットは通常かなりうまくキャッシュされます。


3
1.year.ago不必要なオーバーヘッドです。過去の任意の時間を選んでくださいFri, 01 Jan 1990 00:00:00 GMT
Archonic

6
@Archonic 1990年1月1日は月曜日でした!
トーマスR.コール

1

よりクリーンな方法は、いくつかのロジック(たとえば、application / xml mime-typeのみ)に基づいてCache-Controlヘッダーを変更するRackミドルウェアを作成することです。または、醜いがまだ機能しているアプローチの場合、ActionDispatch :: Response :: DEFAULT_CACHE_CONTROL定数を「no-cache」に変更できます。もちろん、コントローラーやアクションの細分性が必要な場合は、コントローラーで実行することをお勧めします。


1

注意点:キャッシュを条件付きでクリアすることはできません(ユーザーが既にそこにいる場合にbefore_filterのみが呼び出すreset_cache場合など)。キャッシュは無条件にクリアする必要があります。ブラウザは、前回は必要でなかったとしても、今回はリロードする必要があるかどうかを確認するためだけに新しいリクエストを行うわけではないためです。

例:

before_filter :reset_cache, if: :user_completed_demographics?

ブラウザは[戻る]ボタンの元のキャッシュヘッダーを使用するため、ユーザーがそこに行った後に戻ってくるのを防ぐ機能はありません。

before_filter :reset_cache

ただし、(ページを更新し、これを追加する前からキャッシュをクリアした後)は機能しno-cache, no-store, ...ます。これは、最初のリクエストで、ブラウザーがを取得してそれを将来のページの読み込みに適用するためです。


0

no_cache_control 宝石。

すべての応答に対してこれを行う必要がある場合、たとえば侵入テスト(BURP、Detectifyなど)に合格する場合、このGemをRails 4以降にインストールして、すべての応答に次のヘッダーを追加できます。

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

魅力のように機能し、認証を必要とする安全なHTTPS Webアプリケーションを実行するための正しい方法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.