web-dev-qa-db-fra.com

Angular IE Problème de mise en cache pour $ http

Tous les appels ajax envoyés à partir de IE sont mis en cache par Angular et je reçois un 304 response pour tous les appels suivants. Bien que la demande soit la même, la réponse ne sera pas la même dans mon cas. Je veux désactiver ce cache. J'ai essayé d'ajouter le cache attribute à $ http.get mais ça n'a pas aidé. Comment ce problème peut-il être résolu?

249
Rahul

Au lieu de désactiver la mise en cache pour chaque requête GET, je la désactive globalement dans $ 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';
}]);
434
cnmuc

Vous pouvez soit ajouter une chaîne de requête unique (je crois que c’est ce que jQuery fait avec l’option cache: false) à la demande.

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

Une solution peut-être meilleure est que si vous avez accès au serveur, vous pouvez vous assurer que les en-têtes nécessaires sont définis pour empêcher la mise en cache. Si vous utilisez ASP.NET MVCcette réponse pourrait vous aider.

69
Martin

vous pouvez ajouter un intercepteur.

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

vous devez supprimer les lignes console.log après avoir vérifié.

28
dillip pattnaik

J'ai simplement ajouté trois balises méta dans index.html sur le projet angular, et le problème de cache a été résolu sur Internet Explorer.

<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">
14
rtato

Dupliquer ma réponse dans un autre fil .

Pour Angular 2 et plus récent , le moyen le plus simple d’ajouter des en-têtes no-cache en remplaçant 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'
    });
}

Et référencez-le dans votre module:

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

La garantie que je travaillais allait dans ce sens:

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

J'ai dû fusionner 2 des solutions ci-dessus afin de garantir l'utilisation correcte de toutes les méthodes, mais vous pouvez remplacer common par get ou une autre méthode, par exemple put, post , delete pour que cela fonctionne pour différents cas.

9
marksyzm

Cette seule ligne m'a aidé (Angular 1.4.8):

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

PD: Le problème est que IE11 effectue une mise en cache agressive. En regardant dans Fiddler, j'ai remarqué qu'en mode F12, les requêtes envoient "Pragma = no-cache" et que le terminal est demandé à chaque fois que je visite une page. Mais en mode normal, le point final n'a été demandé qu'une fois à la première fois lorsque j'ai visité la page.

8
yamaxim

Pour éviter la mise en cache, une option consiste à donner une URL différente pour la même ressource ou les mêmes données. Pour générer une URL différente, vous pouvez ajouter une chaîne de requête aléatoire à la fin de l'URL. Cette technique fonctionne pour JQuery, Angular ou tout autre type de requête ajax.

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

Je l'obtiens en ajoutant datetime en tant que nombre aléatoire:

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

La solution ci-dessus fonctionnera (rendre l’URL unique en ajoutant dans la chaîne de requête un nouveau paramètre) mais je préfère la solution proposée [ici]: Meilleure façon de prévenir IE Cache dans AngularJS? , qui traitent cela au niveau du serveur car ce n’est pas spécifique à IE. Je veux dire, si cette ressource ne doit pas être mise en cache, faites-la sur le serveur (cela n'a rien à voir avec le navigateur utilisé; c'est intrisic à la ressource).

Par exemple, dans Java avec JAX-RS, faites-le par programme pour JAX-RS v1 ou à la baisse pour JAX-RS v2.

Je suis sûr que tout le monde saura comment le faire

4
rguitter

C'est un peu vieux mais: Des solutions comme est obsolète. Laissez le serveur gérer le cache ou pas cache (dans la réponse). La seule façon de garantir l'absence de mise en cache (en pensant aux nouvelles versions en production) consiste à modifier le fichier js ou css avec un numéro de version. Je fais cela avec webpack.

1
Jens Alenius

J'ai trouvé une meilleure solution: Meilleure façon de prévenir IE Cache dans AngularJS?

Pour les paresseux, voici une solution:

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
1
Vladislav Kurkotov

vous pouvez aussi essayer dans votre service de définir des en-têtes comme par exemple:

 ... 
 import {Injectable} de "@ angular/core"; 
 import {HttpClient, HttpHeaders, HttpParams} de "@ angular/common/http"; 
 ... 
 @Injectable () 
 Classe d'exportation MyService {
 
 En-têtes privés: HttpHeaders; 
 
 
 constructeur (privé http: HttpClient ..) 
 {
 
 
 this.headers = new HttpHeaders () 
 .append ( "Content-Type", "application/json") 
 .Append ("Accepter", "application/json") 
 .Append ("LanguageCulture", this.headersLanguage) 
 .append ("Cache-Control", "no-cache") 
 .append ("Pragma", "no-cache") 
} 
} 
 .... 
1
No Name

Toujours utiliser une approche simple, ajouter un horodatage à chaque demande, pas besoin d'effacer le cache

    let c=new Date().getTime();
    $http.get('url?d='+c)
0
Vaimeo
meta http-equiv="Cache-Control" content="no-cache"

Je viens d'ajouter ceci à View et cela a commencé à fonctionner sur IE. Confirmé pour travailler sur Angular 2.

0
Bharat Raj

Ce problème est dû au problème de cache IE, comme vous l'avez dit, vous pouvez le tester en mode débogage IE en appuyant sur f12 (cela fonctionnera correctement en mode débogage) .IE ne prendra pas les données du serveur à chaque fois que la page appelle, il prend les données du cache. Pour le désactiver, effectuez l’une des opérations suivantes:

  1. ajoutez ce qui suit avec votre URL de demande de service http

// avant (émis)

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

// Après (fonctionne bien)

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

  1. désactiver le cache pour tout le module: -

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

0
Nijas_kp