$ httpのAngular IE Cachingの問題


251

IEから送信されたすべてのajax呼び出しはAngularによってキャッシュされ304 response、その後のすべての呼び出しに対してを取得します。リクエストは同じですが、私の場合、レスポンスは同じではありません。このキャッシュを無効にしたい。cache attribute$ http.getにを追加してみましたが、それでも役に立ちませんでした。この問題はどのように解決できますか?

回答:


439

単一のGET要求ごとにキャッシュを無効にする代わりに、$ httpProviderでグローバルに無効にします。

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }    

    // Answer edited to include suggestions from comments
    // because previous version of code introduced browser-related errors

    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);

78
If-Modified-Sinceヘッダは、IIS +はすべてのhtmlファイル400不正なリクエストを投げるiisnodeせて読み込まngIncludengView。(私は、キャッシングの問題を持っていなかったクロム、からそれらを引っ張っ)ものの、次の2つのヘッダは私のために問題を修正: $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache'; $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
ラングドン

4
私の意見では、この回答は回答としてマークする必要がありますが、Martinが提供するソリューションは機能しますが、実際の修正というよりはハックのようなものです。
Robba 2014年

4
これは私のローカルGETリクエストでは機能しましたが、それにより、GETメソッドの代わりにOPTIONSメソッドを使用し始めたCORSリクエストが1つ発生しました。サードパーティのサーバーはOPTIONSメソッドをサポートしていないため、私の回避策はjQuery.get()を使用してそのリクエストを作成し、応答ハンドラーで$ scope.apply()を使用することです。
ベン・

13
If-Modified-Since = "0"ヘッダーを使用すると、Tomcatが壊れます(0有効な値RFCではないため、ヘッダー日付の解析に問題があります)。Mon, 26 Jul 1997 05:00:00 GMT代わりに値を使用して修正されました。
ロピサン2014年

6
「If-Modified-Since」ヘッダーを使用しなかったため、ヘッダーがなくても機能しました。他の2つだけが必要です。
Michael Mahony、2015年

69

リクエストに一意のクエリ文字列(jQueryがcache:falseオプションを使用して行うことだと思います)をリクエストに追加することもできます。

$http({
    url: '...',
    params: { 'foobar': new Date().getTime() }
})

おそらくより良い解決策は、サーバーにアクセスできる場合、キャッシュを防ぐために必要なヘッダーが設定されていることを確認することです。ASP.NET MVC この答えを使用している場合は役立つかもしれません。


2
$http.get(url+ "?"+new Date().toString())パラメータを使用せず、クエリ文字列に追加するだけの別の表現です。
DavutGürbüz2016年

28

インターセプターを追加できます。

myModule.config(['$httpProvider', function($httpProvider) {
 $httpProvider.interceptors.push('noCacheInterceptor');
}]).factory('noCacheInterceptor', function () {
            return {
                request: function (config) {
                    console.log(config.method);
                    console.log(config.url);
                    if(config.method=='GET'){
                        var separator = config.url.indexOf('?') === -1 ? '?' : '&';
                        config.url = config.url+separator+'noCache=' + new Date().getTime();
                    }
                    console.log(config.method);
                    console.log(config.url);
                    return config;
               }
           };
    });

確認後、console.log行を削除する必要があります。


そして$log、それらを取り出すのを忘れた場合に備えて使用する必要があります。
カールG

2
重要な部分が実行されなかったため、IEで深刻なキャッシュの問題が発生し、空白のページが表示されます。支えられたインターセプターを使用してこの問題を解決しました!+1
raoulinski 2015年

追加のヘッダーを追加した場合に、プリフライトリクエストをトリガーするCORSおよびIEの動作に関する問題を回避するため、これが最良のアプローチだと思います。これは、追加の問題が発生しないようにする最も安全な方法のようです
chrismarx

@dilip pattnaik:-なぜこの問題は角度付きで発生しますか?
MiHawk 2018年

14

角度のあるプロジェクトでindex.htmlに3つのメタタグを追加するだけで、IEでキャッシュの問題が解決しました。

<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Expires" content="Sat, 01 Dec 2001 00:00:00 GMT">

2
index.htmlIE11がAJAXリクエストをキャッシュしていることに気付いたときは、すでにこれらのメタタグ$httpProviderがありました。
walen 2017

14

別のスレッドで私の回答を複製しています

以下のための角度2以降、追加する最も簡単な方法no-cacheオーバーライドすることで、ヘッダをRequestOptions

import { Injectable } from '@angular/core';
import { BaseRequestOptions, Headers } from '@angular/http';

@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
    headers = new Headers({
        'Cache-Control': 'no-cache',
        'Pragma': 'no-cache',
        'Expires': 'Sat, 01 Jan 2000 00:00:00 GMT'
    });
}

そしてあなたのモジュールでそれを参照してください:

@NgModule({
    ...
    providers: [
        ...
        { provide: RequestOptions, useClass: CustomRequestOptions }
    ]
})

これらは、ブラウザのリクエストではなく、サーバーのレスポンスのヘッダーではないでしょうか?(If-Modified-Since上記の方法を使用して過去の日付を設定できると想像できます。)
Arjan

@Vitaliy:-なぜこの問題は角度付きで発生しますか?
MiHawk 2018年

あなたのアプローチはすでにそこにあるすべてのカスタムヘッダーを削除します。したがって、新しいヘッダーオブジェクトを作成する代わりに、次の操作を行います。 headers: req.headers .set('Cache-Control', 'no-cache') .set('Pragma', 'no-cache') .set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
Chamika Goonetilaka

9

私が働いていた保証されたものはこれらの線に沿ったものでした:

myModule.config(['$httpProvider', function($httpProvider) {
    if (!$httpProvider.defaults.headers.common) {
        $httpProvider.defaults.headers.common = {};
    }
    $httpProvider.defaults.headers.common["Cache-Control"] = "no-cache";
    $httpProvider.defaults.headers.common.Pragma = "no-cache";
    $httpProvider.defaults.headers.common["If-Modified-Since"] = "Mon, 26 Jul 1997 05:00:00 GMT";
}]);

私はすべてのメソッドの正しい使用法を保証するために、上記のソリューションの2をマージしなければならなかったが、あなたは置き換えることができcommonget、または他の方法、すなわちputpostdelete異なるケースのためにこの仕事をするために。


これをangular.jsファイルに追加したコードのどこに教えてもらえますか?何行目?
JonathanScialpi

@JonathanScialpiどこに置くかを示すために更新しました。それが無名関数のどこにあるかは重要ではありません。
markyzm 2017年

@marksyzmは、この行の意味を教えてくれますif (!$httpProvider.defaults.headers.get) { $httpProvider.defaults.headers.common = {}; }
Monojit Sarkar 2017年

@MonojitSarkarああ、それはifステートメントでheaders.commonであるはずでした、そのポインタのおかげで
markyzm

1
["If-Modified-Since"] = "0"違法であり、一部のバックエンドで不良リクエストを生成します。それは日付でなければなりません。
jenson-button-event

8

この唯一の行は私を助けました(Angular 1.4.8):

$httpProvider.defaults.headers.common['Pragma'] = 'no-cache';

UPD:問題はIE11が積極的なキャッシングを行うことです。Fiddlerを調べたところ、F12モードではリクエストが「Pragma = no-cache」を送信しており、ページにアクセスするたびにエンドポイントがリクエストされていることに気付きました。しかし、通常モードでは、ページにアクセスしたときにエンドポイントが最初に一度だけ要求されました。


1
ちなみに、この回答はAzureのBLOBストレージからファイルをリクエストするときにCORSの問題を引き起こし、追跡するのが困難でしたが、最終的にこれが原因であることがわかりました。プラグマヘッダーを削除すると、CORSの問題が修正されました(ただし、IEのキャッシュの問題は回復しました)。
keithl8041

7

キャッシュを回避するための1つのオプションは、同じリソースまたはデータに異なるURLを与えることです。別のURLを生成するには、ランダムなクエリ文字列をURLの最後に追加します。この手法は、JQuery、Angular、またはその他のタイプのajaxリクエストで機能します。

myURL = myURL +"?random="+new Date().getTime();

6

日時を乱数として追加して解決しました:

$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
    console.log('your get response is new!!!');
});

:-なぜこの問題は角度付きで発生しますか?
MiHawk 2018年

4

上記の解決策は機能します(クエリ文字列に新しいパラメーターを追加してURLを一意にします)。、これはIEに固有ではないため、サーバーレベルでこれを処理します。つまり、そのリソースをキャッシュしない場合は、サーバーで実行します(これは、使用するブラウザーとは関係がないため、リソースに固有です)。

Javaで例えば、JAX-RSは、それを行うと、プログラムで JAX-RSのためにv1または declativly JAX-RS v2の。

誰もがそれを行う方法を理解すると確信しています


1
詳しく説明できますが、これは適切な方法です。クライアント側では、何をキャッシュするかを選択するべきではありませんが、何をキャッシュする必要があるかをクライアントに通知するのはサーバーでなければなりません。
アルキメデス

私は完全に同意します、これは適切な方法でなければなりません
smnbbrv '16

1

これは少し古いものですが、次のようなソリューションは廃止されました。サーバーがキャッシュを処理するかしないかを(応答で)キャッシュします。キャッシングがないことを保証する唯一の方法(本番環境での新しいバージョンについて考える)は、jsまたはcssファイルをバージョン番号で変更することです。私はこれをwebpackで行います。


1

また、サービスでヘッダーを設定することもできます。例:

...
"@ angular / core"から{Injectable}をインポートします。
"@ angular / common / http"から{HttpClient、HttpHeaders、HttpParams}をインポートします。
...
 @Injectable()
クラスMyService {

    プライベートヘッダー:HttpHeaders;


    コンストラクター(プライベートhttp:HttpClient ..) 
    {


        this.headers = new HttpHeaders()
                    .append( "Content-Type"、 "application / json")
                    .append( "承諾"、 "アプリケーション/ json")
                    .append( "LanguageCulture"、this.headersLanguage)
                    .append( "Cache-Control"、 "no-cache")
                    .append( "プラグマ"、 "キャッシュなし")                   
    }
}
....


0

この問題は、あなたが言ったようにIEキャッシュの問題が原因です。f12を押すと、IEデバッグモードでテストできます(これはデバッグモードで正常に動作します)。IEは、ページが呼び出されるたびにサーバーデータを取得しません。キャッシュからのデータ。これを無効にするには、次のいずれかを実行します。

  1. 以下をhttpサービスリクエストURLに追加します

//前(発行済み)

this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + engagementName、{})

//後(正常に動作)

this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + engagementName + "?DateTime =" + new Date()。getTime()+ ''、{cache:false})

  1. モジュール全体のキャッシュを無効にします:-

$ httpProvider.defaults.headers.common ['Pragma'] = 'no-cache';


0
meta http-equiv="Cache-Control" content="no-cache"

これをViewに追加すると、IEで動作し始めました。Angular 2で動作することを確認しました。


0

オプションは、キャッシュをクリアする必要のないリクエストごとにタイムスタンプを追加するという単純なアプローチを使用することです。

    let c=new Date().getTime();
    $http.get('url?d='+c)

-2

これを試してみてください、それは私にとって同様のケースでうまくいきました:-

$http.get("your api url", {
headers: {
    'If-Modified-Since': '0',
    "Pragma": "no-cache",
    "Expires": -1,
    "Cache-Control": "no-cache, no-store, must-revalidate"
 }
})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.