ブラウザがAJAX呼び出し結果をキャッシュしないようにする


262

を使用して動的コンテンツをロードする$.get()と、結果はブラウザーにキャッシュされるようです。

QueryStringにランダムな文字列を追加すると、この問題は解決されるようです(私はを使用していますnew Date().toString())が、これはハックのように感じられます。

これを達成する他の方法はありますか?または、一意の文字列がこれを達成する唯一の方法である場合、new Date()?以外の提案


$.now()(new Date()。getTime())を毎回行う代わりに、短い表記を使用できます。
Dayson

1
質問のタイトルは少し誤解を招くものです。名前を変更することを検討しましたか?
0112 14

4
承認済みの回答として別の回答を選択することを検討しましたか?
M4N 2015

回答:


241

私はを使用しますnew Date().getTime()。これにより、同じミリ秒内に複数のリクエストが発生しない限り、衝突が回避されます。

$.get('/getdata?_=' + new Date().getTime(), function(data) {
    console.log(data); 
});

編集:この回答は数年前のものです。それはまだ機能します(したがって、私はそれを削除していません)が、これを達成するためのより良い/よりクリーンな方法あります。私の好みはこの方法ですが、この回答は、ページの存続期間中にすべての要求のキャッシュを無効にする場合にも役立ちます。


11
Peter Jの答えのようにjQueryにこれを実行させるほうがきれいなので、私は反対票を投じます。ソリューションは機能しますが、長期的に維持するのはより困難です。
Niklas Wulff、2011年

11
これのどの部分にメンテナンスが必要ですか?jQueryが何をするのと比較すると?
Sunny R Gupta 2013年

5
これは、ことは注目に値するかもしれnew Date().getTime()...コードは次のように利用されていますvar nocache = new Date().getTime(); var path = 'http://hostname.domain.tld/api/somejsonapi/?cache=' + nocache;。私がそれを理解するのに数分かかりました。もちろん?cache、APIが実際に必要としない表現であれば何でもかまいません。
doubleJ

1
+1 ピーターJの回答でさえ、より適切なアプローチをとっていれば、この回答は間違いではなく、悪い回答でもありません。あなたのピーターが(受け入れられたように)ピーターのものより上にあるので、私はDVが作られていると思います。OPは2013
ミシェルエアーズ

1
url = url + (-1 === url.indexOf('?') ? '?' : '&') + "__=" + Number(new Date());

514

以下は、使用するjQueryメソッド($ .get、$。ajaxなど)に関係なく、今後のすべてのAJAXリクエストがキャッシュされるのを防ぎます。

$.ajaxSetup({ cache: false });

7
調査(Fiddler)の結果、jQueryは、とにかく(これらの回答のどこかで説明されているように)タイムスタンプを追加するだけで内部的に実装しているようです。私にとって、.ajaxSetupメソッドはよりクリーンです(私の意見では)
Peter J

8
実際、それはドキュメントの準備ができた呼び出しの中にある必要はありません。
Peter J

19
なぜajaxキャッシングをグローバルに無効にするのですか?ジョナサンの答えがするように、それは呼び出しごとに行われるべきだと思います。
Sunny R Gupta

5
アプリで機能するものは何でも。すべてのAJAX呼び出しに最新のデータが絶対に必要なときはいつでも、商用アプリでこのメソッドを使い続けます。他の人にとっては、キャッシュされたデータは問題ありません。
Peter J

1
link説明:将来のAjaxリクエストのデフォルト値を設定します。その使用は推奨されません。
itwebdeveloper 2015

319

jQueryの$ .get()は結果をキャッシュします。の代わりに

$.get("myurl", myCallback)

$ .ajaxを使用する必要があります。これにより、キャッシュをオフにできます。

$.ajax({url: "myurl", success: myCallback, cache: false});

62
+1これが正解です。キャッシュをグローバルに無効にするPeter Jのソリューションは、悪い習慣のIMOです。
Salman von Abbas

7
ページ/リクエストでは「グローバル」のみであることに注意してください。
Peter J

3
+1:キャッシングはリクエストタイプに固有である必要があります。一部のサーバー要求では、キャッシュが必要な場合があります(サーバーデータが静的な場合)。したがって、すべてをオフにするだけではなく、要求ごとにキャッシュを選択する方が適切です。
2013

1
正解の+1-手動ハッキングではなく、jQueryのメソッドを使用して、呼び出しごとにキャッシュを防止します。
ブレンダンヒル

2
別の良い答え。私にとって、キャッシュをグローバルに無効化することは、ほとんどの場合大きなメリットでした。それはすべて、アプリケーションの設計方法によって異なります。特効薬はありませんが、この状況では、キャッシング用のブール値、コールバック用の関数、モジュール化用のURLを受け入れる関数をお勧めします。手動の「ハック」は問題ありませんが、jQueryを使用している場合は、可能な限りそれらの機能を使用してください。これにより、開発が容易になるだけでなく、ライブラリの将来のアップグレードも容易になります。
Anthony Mason 2016年

24

ここでのすべての回答は、要求されたURLにフットプリントを残します。これは、サーバーのアクセスログに表示されます。

副作用のないヘッダーベースのソリューションが必要でしたが、すべてのブラウザーでWebページのキャッシュを制御する方法に記載されているヘッダーを設定することで解決できることがわかりました

結果は、少なくともChromeで機能する場合、次のようになります。

$.ajax({
   url: url, 
   headers: {
     'Cache-Control': 'no-cache, no-store, must-revalidate', 
     'Pragma': 'no-cache', 
     'Expires': '0'
   }
});


多分ばかげた質問かもしれませんが、私のajaxが画像を返す場合、画像はキャッシュされますか?大量のAmazon S3リクエストを回避するには?
MarceloAgimóvel18年

私は信じています
アイディン

23

別の方法は、ajax呼び出しへの応答を生成するコードでサーバー側からのキャッシュヘッダーを提供しないことです。

response.setHeader( "Pragma", "no-cache" );
response.setHeader( "Cache-Control", "no-cache" );
response.setDateHeader( "Expires", 0 );

17
不正解です。ここで説明したようにIEでは、キャッシュなしヘッダは、XMLHttpRequestの呼び出しのために無視されます。stackoverflow.com/questions/244918/... のDateTime(または私の.ajaxSetup方法)をしているだけのソリューション実際に作業を。
Peter J

私はちょうどそれはIEの特定のだと述べていない、いないキャッシュマントラ私のいつもの貼り付けました
miceuz

2
これにより、すべてのブラウザーのキャッシュがオフになります。response.setHeader( "Cache-Control"、 "max-age = 0、no-cache、no-store、post-check = 0、pre-check = 0");
Chris Broski、2015

13

個人的には、クエリ文字列メソッドはサーバーにヘッダーを設定するよりも信頼性が高いと感じています-プロキシまたはブラウザーがそれをとにかくキャッシュしないという保証はありません(一部のブラウザーは他よりも悪い-名前を付けない)。

私は通常使用してMath.random()いますが、日付の使用に問題はありません(同じ値を2回取得するのに十分な速さでAJAXリクエストを実行するべきではありません)。


2
Date()。getTime()とMath.random()を組み合わせると安全です。補足として、disableCachingが指定されている場合、Ext.AjaxはgetTime()も使用します。
vividos 2008

12

ドキュメントに従う:http : //api.jquery.com/jquery.ajax/

このcacheプロパティは次のもので使用できます。

$.ajax({
    method: "GET",
    url: "/Home/AddProduct?",
    data: { param1: value1, param2: value2},
    cache: false,
    success: function (result) {
        // TODO
    }
});

5

もちろん、「キャッシュを壊す」手法は仕事を成し遂げるでしょうが、サーバーがクライアントに応答がキャッシュされるべきではないことを示したなら、これは最初に起こりません。場合によっては、応答をキャッシュすることが有益な場合とそうでない場合があります。サーバーにデータの正しい存続期間を決定させます。後で変更することもできます。UIコードのさまざまな場所から行うよりも、サーバーから行うほうがはるかに簡単です。

もちろん、サーバーを制御できない場合、これは役に立ちません。


5

GETの代わりにPOSTリクエストを使用するのはどうですか...?(とにかくあなたがすべきか...)


私はそれがより良い解決策だと思いますが、残念ながら私は(どういうわけか)GETリクエストしか実行できません。つまり、今のところ新しいDate()。getTime()です。
Salamander2007

他の人がそれから学ぶことができるように、あなたの回答にいくつかの説明を追加してください- なぜ POSTリクエストが必要なのですか?
Nico Haase

5

本当の問題は、これをキャッシュしないようにする必要がある理由です。常に変更されるためにキャッシュしない場合は、サーバーはリソースをキャッシュしないように指定する必要があります。それが時々変化するだけの場合(依存するリソースの1つが変化する可能性があるため)、クライアントコードがそれを知る方法を持っている場合、ハッシュまたは最終更新日から計算されるURLにダミーパラメータを追加できます。それらのリソース(これはMicrosoft Ajaxスクリプトリソースで行っていることであり、永久にキャッシュすることができますが、新しいバージョンは表示されたとおりに提供できます)。クライアントが変更を認識できない場合、正しい方法はサーバーがHEADリクエストを適切に処理し、キャッシュされたバージョンを使用するかどうかをクライアントに通知することです。ランダムパラメータを追加したり、キャッシュしないようにクライアントから指示したりするのは間違っているように思えます。キャッシュ可能性はサーバーリソースのプロパティであるため、サーバー側で決定する必要があります。自問するもう1つの質問は、このリソースが本当にGETを通じて提供されるのか、それともPOSTを経由するのかということです。これはセマンティクスの問題ですが、セキュリティにも影響します(サーバーがGETを許可した場合にのみ機能する攻撃があります)。POSTはキャッシュされません。


6
キャッシュポリシーを制御していないプロキシサーバーを経由している場合はどうなりますか?アプリが毎回新しいリクエストを明示的に行う必要がある場合はどうなりますか?物事に対する答えは、常に明確な白黒であるとは限らず、常に灰色の領域があります。
7wp 2011年

確かに、それは常に明確であるとは限りません。しかし、この答えを見て私は自分の仮定に疑問を投げかけ、私の問題の根本的な原因を見つけるようになりました。それはすべての人に当てはまるわけではありませんが、それは私を助けました。ここを読んでいる場合は、それも考慮する必要があります。
Jonathan Tran

これは私を助けました、ResponseCachingはデフォルトでサーバー側60mに設定されました。キャッシュなしに変更し、クライアントでのキャッシュを停止しました。
mattygee

4

たぶん、代わりに$ .ajax()を見る必要があります(jQueryを使用している場合は、このようになります)。見てください:http : //docs.jquery.com/Ajax/jQuery.ajax#optionsとオプション「キャッシュ」。

別のアプローチは、サーバー側でキャッシュする方法を調べることです。


1
残念ながら、いくつかの調査の後、$。ajax()を使用してcache = falseを設定しても、基本的に同じことを行います。jQueryは乱数をクエリ文字列に追加し、既存のクエリ文字列をチェックしません。したがって、$。get()を使用するだけで十分だと思います。
Salamander2007

ああオーケー。試したことはありませんが、ドキュメントで何かを見たことがあることを思い出しました:)
finpingvin

$ .ajaxを使用する必要すらありません。単に.ajaxSetupを使用します。
ピーターJ

3

与えられた優れた答えへの小さな追加:JavaScriptを使用していないユーザーのために非Ajaxバックアップソリューションで実行している場合、とにかくそれらのサーバー側ヘッダーを正しく取得する必要があります。私はそれをあきらめるものを理解していますが、これは不可能ではありません;)

適切なヘッダーの完全なセットを提供するSOに関する別の質問があると確信しています。私は完全に有罪判決を受けたわけではありません。


3

モバイルSafariでキャッシュするため、モバイルSafari のcacheオプションを使用している場合、$.ajaxSetup()POSTにタイムスタンプを使用する必要があるようです。$.ajax()(あなたがに向けられている$.ajaxSetup())に関するドキュメントによれば:

キャッシュをfalseに設定すると、HEADおよびGETリクエストでのみ正しく機能します。GETパラメータに「_ = {timestamp}」を追加することで機能します。IE8では、GETによってすでに要求されているURLに対してPOSTが行われる場合を除いて、このパラメーターは他のタイプの要求には必要ありません。

そのため、このオプションを単独で設定しても、上記のケースでは役に立ちません。


2

基本的にcache:false;は、進行状況に応じてコンテンツが変化すると思う場所にajaxを追加するだけです。そして、コンテンツが変更されない場所では、これを省略できます。このようにして、毎回新しい応答を取得します



2

これで、ajaxリクエストでキャッシュオプションを有効/無効にすることで、次のように簡単に実行できます。

$(function () {
    var url = 'your url goes here';
    $('#ajaxButton').click(function (e) {
        $.ajax({
            url: url,
            data: {
                test: 'value'
            },
                cache: true, //cache enabled, false to reverse
                complete: doSomething
            });
        });
    });
    //ToDo after ajax call finishes
    function doSomething(data) {
        console.log(data);
    }
});

3
6年後、あなたはジョナサンと同じ応答を提供していますか?ಠ_ಠ
redent84

質問が投稿されてから6年が経過したことがわかります。そして、その質問に対する私の答えは他の人とは異なり、言うまでもなく、それが現在の正しい答えです。そのような質問に答えることは、コミュニティと初心者のための「質問者」のためではありません!とにかく説明を追加してくれてありがとう!
Omar El Don

そして、あなたのものとこの1つのstackoverflow.com/a/735084/469218の違いは何ですか?
redent84

初心者がこんな質問をするという観点からは、明快かもしれません!
Omar El Don

1

IE 9を使用している場合は、コントローラークラス定義の前で以下を使用する必要があります。

[OutputCache(NoStore = true、Duration = 0、VaryByParam = "*")]

パブリッククラスTestController:Controller

これにより、ブラウザがキャッシュされなくなります。

このリンクの詳細:http : //dougwilsonsa.wordpress.com/2011/04/29/disabling-ie9-ajax-response-caching-asp-net-mvc-3-jquery/

実際、これで私の問題は解決しました。


1

@Athasachが言ったように、jQueryドキュメントによると、 $.ajaxSetup({cache:false}) GETリクエストとHEADリクエスト以外では機能しません。

あなたは送り返す方が良いです Cache-Control: no-cacheとにかくサーバーからヘッダー。これにより、問題を明確に分離できます。

もちろん、これはプロジェクトに属していないサービスURLには機能しません。その場合、サードパーティサービスをクライアントコードから呼び出すのではなく、サーバーコードからプロキシすることを検討してください。


1

.net ASP MVCを使用している場合は、エンドポイント関数に次の属性を追加して、コントローラーアクションのキャッシュを無効にします。

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]

それをさらに説明できますか?その配列はAJAXとどのように関連していますか?
ニコHaase

これは配列ではなく、MVCコントローラーアクションの属性です
マリウス

0

ヘッダーを追加

headers: {
                'Cache-Control':'no-cache'
            }

他の人がそれから学ぶことができるようにあなたの答えにいくつかの説明を追加してください- そのようなヘッダーはどこに追加されるべきですか?
ニコHaase

-3

Math.random() リクエストURLに追加する


2
これは不安定な結果をもたらします。
aj.toulan

Math.randomはurl?_ = [Math.Random()]のようにパラメーターとしてのみ機能し、不安定な結果とは関係ありません。
xiaoyifang 2014

4
私はあなたが何をしていたのか理解しています。私は単にMath.Random()が時々あなたに同じ数値を2度与えるとコメントしていました。システムを不確実性で満たす場合、それらは互いの上に追加されるだけです。
aj.toulan 2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.