web-dev-qa-db-ja.com

Angular 2でIE11キャッシュGET呼び出しを防止

GET呼び出しでリストを返すレストエンドポイントがあります。また、新しいアイテムを追加するPOSTエンドポイントと、それらを削除するDELETEもあります。これはFirefoxおよびChromeで機能し、POSTおよびDELETEはIE11で機能します。ただし、IE11のGETは、ページの初期読み込みでのみ機能します。更新すると、キャッシュされたデータが返されます。私はAngular 1でこの動作に関する投稿を見ましたが、Angular 2(リリース候補1)には何もありません。

65
cmaynard

Angular 2以降の場合、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 }
    ]
})
56

今日、私もこの問題を抱えていました(IEのことです)。私のプロジェクトでは、httpclientではないBaseRequestOptionsを使用しています。 Http_Interceptorを使用して解決する必要があります!

import { HttpHandler,
    HttpProgressEvent,
    HttpInterceptor,
    HttpSentEvent,
    HttpHeaderResponse,
    HttpUserEvent,
    HttpRequest,
    HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

export class CustomHttpInterceptorService implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler):
      Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
      const nextReq = req.clone({
        headers: req.headers.set('Cache-Control', 'no-cache')
          .set('Pragma', 'no-cache')
          .set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
          .set('If-Modified-Since', '0')
      });

      return next.handle(nextReq);
  }
}

モジュール提供

@NgModule({
    ...
    providers: [
        ...
        { provide: HTTP_INTERCEPTORS, useClass: CustomHttpInterceptorService, multi: true }
    ]
})
36
Jimmy Ho

Stackoverflow応答を転送します Angular IE Caching issue for $ http 、ヘッダー 'Pragma'、 'no-cache'、 'If-Modified-Since'を各 ' GET 'リクエスト。

インターセプターのシナリオはangular 2ではサポートされなくなりました。したがって、httpをここで説明されているように拡張する必要があります angular2でhttpinterceptorに相当するものは何ですか?

Angular 4.3には、インターセプターをサポートする HttpClient サービスが含まれるようになりました。

6
dimeros

編集:以下のコメントを参照-これは必要ありません(ほとんどの場合)。

上記のJimmy Hoの答えを拡張して、API呼び出しのキャッシュのみを防止し、キャッシュされることで利益が得られる他の静的コンテンツは防止しません。 API呼び出しはすべて「/ api /」を含むURLに対するものなので、リクエストされたURLに「/ api /」が含まれている場合にのみキャッシュヘッダーを追加するチェックでJimmy Hoのコードを修正しました。

import { HttpHandler,
    HttpProgressEvent,
    HttpInterceptor,
    HttpSentEvent,
    HttpHeaderResponse,
    HttpUserEvent,
    HttpRequest,
    HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

export class CustomHttpInterceptorService implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler):
    Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
    // Only turn off caching for API calls to the server.
    if (req.url.indexOf('/api/') >= 0) {
        const nextReq = req.clone({
            headers: req.headers.set('Cache-Control', 'no-cache')
                .set('Pragma', 'no-cache')
                .set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
                .set('If-Modified-Since', '0')
        });

        return next.handle(nextReq);
    } else {
        // Pass the request through unchanged.
        return next.handle(req);
    }
}

}

3
AndrWeisR

少し遅れましたが、同じ問題に遭遇しました。 Angular 4.Xの場合、IEによるキャッシングを防ぐために末尾に乱数を追加するカスタムHttpクラスを作成しました。これは、ダイメロスによる2番目のリンクに基づいています( angular2でhttpinterceptorに相当するものは何ですか? )。 警告:100%バグがないことは保証されません。

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Http, Response, XHRBackend, RequestOptions, RequestOptionsArgs, 
URLSearchParams } from '@angular/http';

@Injectable()
export class NoCacheHttp extends Http {
    constructor(backend: XHRBackend, options: RequestOptions) {
        super(backend, options);
    }

    get(url: string, options?: RequestOptionsArgs): Observable<Response> {
        //make options object if none.
        if (!options) {
            options = { params: new URLSearchParams() };
        }
        //for each possible params type, append a random number to query to force no browser caching.
        //if string
        if (typeof options.params === 'string') {
            let params = new URLSearchParams(options.params);
            params.set("k", new Date().getTime().toString());
            options.params = params;

        //if URLSearchParams
        } else if (options.params instanceof URLSearchParams) {
            let params = <URLSearchParams>options.params;
            params.set("k", new Date().getTime().toString());

        //if plain object.
        } else {
            let params = options.params;
            params["k"] = new Date().getTime().toString();
        }
        return super.get(url, options);
    }
}
0
Chris Moore

メタHTMLタグを使用してブラウザーのキャッシュを無効にします。

<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0">
<meta http-equiv="expires" content="0">
<meta http-equiv="pragma" content="no-cache">
0
Mahi