Une meilleure façon de prévenir le cache IE dans AngularJS?

J’utilise actuellement la ressource service / $ pour effectuer des appels ajax (GET dans ce cas), et IE met en cache les appels pour que les nouvelles données ne puissent pas être extraites du serveur. J’ai utilisé une technique trouvée par googler pour créer un nombre aléatoire et l’append à la demande, afin qu’IE ne vienne pas en cache pour les données.

Y a-t-il un meilleur moyen que d’append le cacheKill à chaque requête?

code usine

.factory('UserDeviceService', function ($resource) { return $resource('/users/:dest', {}, { query: {method: 'GET', params: {dest: "getDevicesByUserID"}, isArray: true } }); 

Appel du contrôleur

 $scope.getUserDevices = function () { UserDeviceService.query({cacheKill: new Date().getTime()},function (data) { //logic }); } 

En tant que binarygiant demandé, je publie mon commentaire en réponse. J’ai résolu ce problème en ajoutant des en-têtes No-Cache à la réponse côté serveur. Notez que vous devez le faire uniquement pour les requêtes GET, les autres requêtes semblent fonctionner correctement.

binarygiant a posté comment vous pouvez le faire sur node / express. Vous pouvez le faire dans ASP.NET MVC comme ceci:

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

Comme décrit dans l’un de mes autres articles , vous pouvez désactiver la mise en cache 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'; }]); 

Pour ceux qui utilisent ASP.NET Web API 2, la solution équivalente serait la suivante (l’API Web n’utilise pas la même logique de mise en cache que MVC):

 public class NoCacheHeaderFilter : ActionFilterAtsortingbute { public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (actionExecutedContext.Response != null) // can be null when exception happens { actionExecutedContext.Response.Headers.CacheControl = new CacheControlHeaderValue { NoCache = true, NoStore = true, MustRevalidate = true }; actionExecutedContext.Response.Headers.Pragma.Add(new NameValueHeaderValue("no-cache")); if (actionExecutedContext.Response.Content != null) // can be null (for example HTTP 400) { actionExecutedContext.Response.Content.Headers.Expires = DateTimeOffset.UtcNow; } } } } 

puis attachez-le dans WebApiConfig.cs:

 public static void Register(HttpConfiguration config) { .... config.Filters.Add(new NoCacheHeaderFilter()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } 

Activer noCache dans l’instance is était le meilleur moyen d’y parvenir:

Dans node / express cela fonctionne pour empêcher IE de mettre en cache ces requêtes:

 app.use(function noCache(req, res, next) { res.header("Cache-Control", "no-cache, no-store, must-revalidate"); res.header("Pragma", "no-cache"); res.header("Expires", 0); next(); }); 

vous pouvez append un intercepteur pour générer une URL de requête unique. Vous pouvez également supprimer les appels à console.log

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

Je le fais résoudre par:

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

Bien que cette approche:

 myModule.config(['$httpProvider', function($httpProvider) { //initialize get if not there if (!$httpProvider.defaults.headers.get) { $httpProvider.defaults.headers.get = {}; } //disable IE ajax request caching $httpProvider.defaults.headers.get['If-Modified-Since'] = '0'; }]); 

Est correct, “0” n’est pas une valeur valide pour l’en-tête If-Modified-Since. Il doit s’agir d’une date HTTP valide, par exemple:

 If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT 

Selon les spécifications :

Un destinataire DOIT ignorer le champ d’en-tête If-Modified-Since si le
valeur de champ reçue n’est pas une date HTTP valide ou si la requête
méthode n’est ni GET ni HEAD.

Donc, mieux vaut être prudent que désolé et utiliser une date réelle dans le passé.

Si vous contrôlez la sortie du serveur, il serait préférable d’y append des en-têtes de mise en cache.

Koajs équivalent de la réponse de binarygiant:

 app.use(route.get('*', noCache)); function* noCache(path, next){ this.set('cache-control', 'no-cache, no-store, must-revalidate'); this.set('pragma', 'no-cache'); this.set('expires', 0); yield next; } 

Ma solution ajoutait Cache-Control: no-cache tête Cache-Control: no-cache sur le serveur, en ajoutant $templateCache.remove() avant de changer d’état. J’utilise un ui / ui-routeur angular. J’avais un problème avec IE11 et le navigateur Edge.

 $templateCache.remove('/partials/details.html'); $state.go('details'); 

Une solution évidente consiste à utiliser des URL uniques. Mais comment modifier les URL du routeur après l’initialisation? La désactivation des caches du navigateur n’est pas une option, car nous en avons besoin pour des opérations normales. Vous pouvez supprimer des modèles de $ templateCache lorsque ceux-ci ne sont plus nécessaires. ( http://docs.angularjs.org/api/ng . $ templateCache). Ces nouveaux fichiers sont ajoutés au cache dès que le téléchargement est terminé.