Problème de mise en cache angulaire pour $ http
tous les appels ajax qui sont envoyés par 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 cette cache. J'ai essayé d'ajouter le cache attribute
à $http.obtenir, mais encore cela n'a pas aide. Comment ce problème peut-il être résolu?
17 réponses
au lieu de désactiver la mise en cache pour chaque requête GET, je la désactiverai globalement dans le $ httprovider:
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';
}]);
vous pouvez soit ajouter un querystring unique (je crois que c'est ce que jQuery fait avec l'option cache: false) à la requête.
$http({
url: '...',
params: { 'foobar': new Date().getTime() }
})
une meilleure solution est peut-être si vous avez accès au serveur, alors 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 MVC
cette réponse pourrait vous aider.
, 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 console.lignes de journalisation après vérification.
j'ai simplement ajouté trois meta tags dans index.html sur le projet angulaire, et le problème de cache a été résolu sur 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">
pour angulaire 2 et plus récente , la façon la plus facile d'ajouter des en-têtes mentionnés est de remplacer RequestOptions
classe utilisée par Http
service:
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érence dans votre module:
@NgModule({
...
providers: [
...
{ provide: RequestOptions, useClass: CustomRequestOptions }
]
})
la garantie que je travaillais était quelque chose dans ce genre:
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 du fusionner 2 des solutions ci-dessus afin de garantir l'utilisation correcte pour toutes les méthodes, mais vous pouvez remplacer common
par get
ou une autre méthode i.e. put
, post
, delete
pour que ça marche dans différents cas.
cette seule ligne m'a aidé (angulaire 1.4.8):
$httpProvider.defaults.headers.common['Pragma'] = 'no-cache';
UPD: le problème est que IE11 fait de la mise en cache agressive. En regardant Fiddler, j'ai remarqué que dans le mode F12 les requêtes envoient "Pragma=no-cache" et endpoint est demandé chaque fois que je visite une page. Mais en mode normal, endpoint n'a été demandé qu'une seule fois lors de la première visite de la page.
Je l'obtiens résolu en ajoutant datetime comme un nombre aléatoire:
$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
console.log('your get response is new!!!');
});
pour éviter la mise en cache, une option est de 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 les requêtes jQuery, Angular ou autre type ajax.
myURL = myURL +"?random="+new Date().getTime();
Solution ci-dessus fonctionnera (rendre l'url unique en ajoutant dans le querystring un nouveau param) mais je préfère la solution propose [ici]: meilleure façon D'empêcher IE Cache à AngularJS? , qui gèrent cela au niveau du serveur car il n'est pas spécifique à IE. Je veux dire, si cette ressource ne devrait pas être mise en cache, faites-le sur le serveur (ce qui n'a rien à voir avec le navigateur utilisé; c'est intrisic à la ressource).
par exemple en java avec JAX-RS le faire programmant de JAX-RS v1 ou declativly de JAX-RS v2.
je suis sûr que quelqu'un va comprendre comment le faire", 151930920"
j'ai trouvé une meilleure solution: meilleure façon d'empêcher IE Cache à AngularJS?
pour les paresseux voici une solution:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
// return your response
}
C'est un peu trop vieux mais: Solutions Comme est obsolète. Laisser le serveur gérer le cache ou non (dans la réponse). La seule façon de garantir l'absence de mise en cache (penser aux nouvelles versions en production) est de changer le fichier js ou css avec un numéro de version. Je fais ça avec webpack.
vous pouvez également essayer dans votre servce de définir des en-têtes comme par exemple:
... import { Injectable } from "@angular/core"; import { HttpClient, HttpHeaders, HttpParams } from "@angular/common/http"; ... @Injectable() export class MyService { private headers: HttpHeaders; constructor(private 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") } } ....
ce problème est dû au problème de cache IE comme vous l'avez dit, Vous pouvez le tester en mode de débogage IE en appuyant sur f12 (cela fonctionnera très bien en mode de 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 désactiver cette option, faites l'une des opérations suivantes:
- ajoutez ce qui suit à l'url de votre demande de service http
//avant (délivré)
.httpService.obtenir(ce.serviceUrl + " / eAMobileService.svc / ValidateEngagmentName / "+ engagementName, {})
"151970920 //Après (fonctionne bien)
.httpService.obtenir(ce.serviceUrl + " / eAMobileService.svc/ ValidateEngagmentName / " + engagementName + "?DateTime= " + new Date ().getTime ()+", { cache: false})
- désactiver l' cache pour L'ensemble du Module: -
$httpProvider.défaut.tête.common ['Pragma'] = 'no-cache';
meta http-equiv="Cache-Control" content="no-cache"
je viens d'ajouter ceci à View et il a commencé à travailler sur IE. Confirmé pour travailler sur Angular 2.
toujours utiliser une approche simple ajouter une horodatage avec chaque requête Pas besoin de vider le cache
let c=new Date().getTime();
$http.get('url?d='+c)
essayez ceci, cela a fonctionné pour moi dans un cas similaire: -
$http.get("your api url", {
headers: {
'If-Modified-Since': '0',
"Pragma": "no-cache",
"Expires": -1,
"Cache-Control": "no-cache, no-store, must-revalidate"
}
})