IEから送信されたすべてのAjax呼び出しはAngularによってキャッシュされ、それ以降のすべての呼び出しについて304 response
が返されます。要求は同じですが、私の場合は応答が同じになるわけではありません。このキャッシュを無効にしたいのですが。私はcache attribute
を$ http.getに追加しようとしましたが、それでも助けにはなりませんでした。この問題はどのように解決できますか?
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';
}]);
リクエストに独自のクエリ文字列を追加することもできます(これがjQueryがcache:falseオプションを使用して行うものであると私は信じています)。
$http({
url: '...',
params: { 'foobar': new Date().getTime() }
})
おそらくもっと良い解決策は、サーバーにアクセスできる場合、必要なヘッダーがキャッシュを防ぐために設定されていることを確認できることです。 ASP.NET MVC
を使っているなら、この答え が役に立つかもしれません。
インターセプターを追加することができます。
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の行を削除する必要があります。
Angularプロジェクトで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">
私の答えを別のスレッドにコピーする。
Angular 2以降の場合、RequestOptions
をオーバーライドしてno-cache
ヘッダーを追加する最も簡単な方法は次のとおりです。
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 }
]
})
私が働いていた保証されたものはこれらの線に沿った何かでした:
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つをマージする必要がありましたが、common
をget
または他のメソッド、つまりput
、post
、delete
で置き換えることができます。
この唯一の行は私を助けてくれました(Angular 1.4.8):
$httpProvider.defaults.headers.common['Pragma'] = 'no-cache';
UPD:問題はIE11が積極的なキャッシングをしていることです。私がFiddlerを調べていたとき、私はF12モードでリクエストが "Pragma = no-cache"を送信していて、エンドポイントは私がページを訪れるたびにリクエストされることに気づきました。しかし、通常モードでは、私がページにアクセスしたときに初めてエンドポイントが一度だけ要求されました。
キャッシュを避けるために、1つの選択肢は同じリソースまたはデータに対して異なるURLを与えることです。別のURLを生成するには、URLの末尾にランダムなクエリ文字列を追加します。この手法は、JQuery、Angular、またはその他のタイプのajaxリクエストに有効です。
myURL = myURL +"?random="+new Date().getTime();
追加された日時を乱数として解決します。
$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
console.log('your get response is new!!!');
});
上記の解決策はうまくいきます(クエリ文字列に新しいパラメータを追加してURLを一意にします)が、ここで提案する解決策をお勧めします: IE Cache inを防ぐより良い方法AngularJS? 。これはIEに固有のものではないため、サーバーレベルでこれを処理します。つまり、そのリソースをキャッシュするべきではない場合は、サーバー上で実行します(これは、使用されているブラウザとは関係がないため、リソースに固有のものです)。
たとえば、JAX-RSを使用するJavaでは、JAX-RS v1の場合は programatically 、JAX-RSの場合は declativly を実行v2。
私は誰もがそれを行う方法を考え出すと確信しています
これは少し古いですが:のような解決策は時代遅れです。サーバーにキャッシュを処理させるか、させないでください(応答で)。キャッシングしないことを保証する唯一の方法(プロダクションで新しいバージョンについて考える)は、jsファイルまたはcssファイルをバージョン番号で変更することです。私はこれをwebpackでやっています。
私はより良い解決策を見つけました: AngularJSでIEキャッシュを防ぐためのより良い方法?
怠け者のためにここに解決策があります:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
// return your response
}
また、あなたはあなたのservceでヘッダを設定するように試すことができます。例えば:
... import {Injectable}を "@ angular/core"からインポートする; {HttpClient、HttpHeaders、HttpParams}を "@ angular/common/http"からインポートする; ... @Injectable() エクスポートクラスMyService { プライベートヘッダ:HttpHeaders; [コンストラクタ(プライベートhttp:HttpClient ..) { this.headers = new HttpHeaders() .append( "Content-Type"、 "application/json") .append( "Accept"、 "application/json") .append( "LanguageCulture"、this.headersLanguage) .append( "Cache-Control"、 "no-cache") .append( "Pragma"、 "no-cache") } } ] ....
常にシンプルなアプローチを使用し、リクエストごとにタイムスタンプを追加します。キャッシュをクリアする必要はありません
let c=new Date().getTime();
$http.get('url?d='+c)
meta http-equiv="Cache-Control" content="no-cache"
これをViewに追加したところ、IEで作業を始めました。 Angular 2で動作することを確認しました。
あなたが言ったようにこの問題はIEキャッシュ問題によるものです、あなたはf12を押すことによってそれをIEデバッグモードでテストすることができます(これはデバッグモードでうまく働きます)。ページが呼び出されるたびにサーバーデータがキャッシュからデータを取得します。これを無効にするには、次のいずれかを実行します。
//前(発行済み)
this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + conferenceName、{})
//後(正常に動作)
this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + conferenceName + "?DateTime =" + new Date()。getTime()+ ''、{キャッシュ:false})
$ httpProvider.defaults.headers.common ['Pragma'] = 'no-cache';