Prevent IE11 caching GET call in Angular 2

前端 未结 7 565
甜味超标
甜味超标 2020-11-28 09:19

I have a rest endpoint that returns a list on a GET call. I also have a POST endpoint to add new items and a DELETE to remove them. This works in Firefox and Chrome, and the

相关标签:
7条回答
  • 2020-11-28 09:24

    A little late, but I ran into the same problem. For Angular 4.X I wrote a custom Http class to append a random number to the end to prevent caching by IE. It is based on the 2nd link by dimeros (What is httpinterceptor equivalent in angular2?). Warning: not guaranteed to be 100% bug free.

    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 讨论(0)
  • 2020-11-28 09:26

    For Angular 2 and newer, the easiest way to add no-cache headers by overriding 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'
        });
    }
    

    Module:

    @NgModule({
        ...
        providers: [
            ...
            { provide: RequestOptions, useClass: CustomRequestOptions }
        ]
    })
    
    0 讨论(0)
  • 2020-11-28 09:36

    Disable browser caching with meta HTML tags:-

    <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 讨论(0)
  • 2020-11-28 09:37

    As answered above, you can use http request interceptor to modify or set a new header on the request. Below is a much simpler way of setting headers on http request interceptor for Later angular versions(Angular 4+). This approach would only set or update a certain request header. This is to avoid removing or overriding some important headers like the authorization header.

    // cache-interceptor.service.ts
    import { Injectable } from '@angular/core';
    import {
      HttpInterceptor,
      HttpRequest,
      HttpHandler,
    } from '@angular/common/http';
    
    @Injectable()
    export class CacheInterceptor implements HttpInterceptor {
    
      intercept(req: HttpRequest<any>, next: HttpHandler) {
        const httpRequest = req.clone({
          headers: req.headers
            .set('Cache-Control', 'no-cache')
            .set('Pragma', 'no-cache')
            .set('Expires', 'Sat, 01 Jan 2000 00:00:00 GMT')
        })
    
        return next.handle(httpRequest)
      }
    }
    
    // app.module.ts
    
      import { HTTP_INTERCEPTORS } from '@angular/common/http'
      import { CacheInterceptor } from './cache-interceptor.service';
    
      // on providers
      providers: [{ provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }]
    
    0 讨论(0)
  • 2020-11-28 09:38

    Edit: See comment below - this is not necessary (in the vast majority of cases).

    Expanding on Jimmy Ho's answer above, I only want to prevent caching of my API calls, and not other static content which will benefit from being cached. All of my API calls are to URLs that contain "/api/", so I amended Jimmy Ho's code with a check that only adds the cache headers if the requested URL contains "/api/":

    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);
        }
    }
    

    }

    0 讨论(0)
  • 2020-11-28 09:41

    Forward the stackoverflow response Angular IE Caching issue for $http, you should add the headers 'Pragma', 'no-cache', 'If-Modified-Since' to each 'GET' request.

    The interceptor's scenario is not supported to angular 2 anymore. So you should extend the http as it is described here What is httpinterceptor equivalent in angular2?.

    Angular 4.3 now includes the HttpClient service, which supports interceptors.

    0 讨论(0)
提交回复
热议问题