it-swarm.com.de

Verhindern Sie, dass der IE11-GET-Aufruf in Angular 2 zwischengespeichert wird

Ich habe einen Rest-Endpunkt, der eine Liste bei einem GET-Aufruf zurückgibt. Ich habe auch einen Endpunkt POST, um neue Elemente hinzuzufügen, und ein DELETE, um sie zu entfernen. Dies funktioniert in Firefox und Chrome, und POST und DELETE funktionieren in IE11. Das GET in IE11 funktioniert jedoch nur beim ersten Laden der Seite. Beim Aktualisieren werden zwischengespeicherte Daten zurückgegeben. Ich habe einen Beitrag über dieses Verhalten in Angular 1 gesehen, aber nichts für Angular 2 (Veröffentlichungskandidat 1).

58
cmaynard

Für Angular 2 und neuere der einfachste Weg, No-Cache-Header hinzuzufügen, indem Sie RequestOptions überschreiben:

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

Modul:

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

Heute hatte ich auch dieses Problem, (verdammter IE). In meinem Projekt verwende ich httpclient, das ist nicht BaseRequestOptions. Wir sollten Http_Interceptor verwenden, um es zu lösen!

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

Modul zur Verfügung stellen

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

Stackoverflow-Antwort weiterleiten Angular IE Caching-Problem für $ http . Sie sollten die Header 'Pragma', 'no-cache', 'If-Modified-Since' zu jeder 'GET'-Anforderung hinzufügen. 

Das Szenario des Interceptors wird von Winkel 2 nicht mehr unterstützt. Sie sollten also das http so erweitern, wie es hier beschrieben wird Was ist der httpinterceptor-Äquivalent in angle2?

Angular 4.3 enthält jetzt den Dienst " HttpClient ", der Interzeptoren unterstützt.

6
dimeros

Bearbeiten : Siehe Kommentar unten - dies ist nicht erforderlich (in der überwiegenden Mehrzahl der Fälle).

Ausgehend von der obigen Antwort von Jimmy Ho möchte ich nur das Zwischenspeichern meiner API-Aufrufe verhindern, nicht aber andere statische Inhalte, die vom Zwischenspeichern profitieren. Alle meine API-Aufrufe beziehen sich auf URLs, die "/ api /" enthalten. Daher habe ich den Code von Jimmy Ho durch einen Haken ergänzt, der nur die Cache-Header hinzufügt, wenn die angeforderte URL "/ api /" enthält:

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

}

2
AndrWeisR

Ein bisschen spät, aber ich hatte das gleiche Problem. Für Angular 4.X habe ich eine benutzerdefinierte Http-Klasse geschrieben, um eine Zufallszahl an das Ende anzuhängen, um das Zwischenspeichern durch IE zu verhindern. Es basiert auf der 2. Verknüpfung von Dimeros ( Was ist httpinterceptor-Äquivalent in angle2? ). Warnung: nicht garantiert zu 100% fehlerfrei.

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

Deaktivieren der Browser-Zwischenspeicherung mit 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
Mahi