Meilleure façon D'empêcher IE Cache à AngularJS?

j'utilise actuellement service/$ressource pour faire des appels ajax (GET dans ce cas), et C'est à dire cache les appels de sorte que les nouvelles données ne peuvent pas être récupérées à partir du serveur. J'ai utilisé une technique que j'ai trouvé en googlant pour créer un nombre aléatoire et l'ajouter à la requête, afin QU'IE ne va pas dans le cache pour les données.

y a-t-il un meilleur moyen que d'ajouter 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
        });
    }
59
demandé sur Ufuk Hacıoğulları 2013-06-07 00:44:01

10 réponses

comme binarygiant l'a demandé, je poste mon commentaire comme une réponse. J'ai résolu ce problème en ajoutant des en-têtes sans Cache à la réponse côté serveur. Notez que vous devez faire cela uniquement pour les requêtes GET, les autres requêtes semblent fonctionner correctement.

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

[OutputCache(NoStore = true, Duration = 0, VaryByParam = "None")]
public ActionResult Get()
{
    // return your response
}
35
répondu Ufuk Hacıoğulları 2013-06-07 23:45:44

comme décrit dans l'un de mes autres posts , vous pouvez désactiver la mise en cache globale dans le $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';
}]);
49
répondu cnmuc 2017-05-23 12:18:18

pour les utilisateurs ASP.NET 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 : ActionFilterAttribute
{
    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 le joindre 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 }
    );
}
33
répondu UserControl 2014-12-12 11:57:01

activer noCache dans l'instance is était le meilleur moyen d'accomplir ceci:

dans node / express ceci fonctionne pour empêcher IE de cacher 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();
});
32
répondu binarygiant 2016-05-26 16:42:10

vous pouvez ajouter un intercepteur pour générer une url de requête unique. Vous pouvez également supprimer la console.les appels du journal

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;
               }
           };
    });
12
répondu dillip pattnaik 2014-01-27 17:38:46

Je l'obtiens résolu par:

$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
    console.log('your get response is new!!!');
});
4
répondu khichar.anil 2014-07-25 10:51:11

alors 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 le spec :

un destinataire doit ignorer le champ d'en-tête "If-Modified-Since" si le champ

received field-value n'est pas une date HTTP valide, ou si la requête

la méthode n'est ni GET ni HEAD.

donc mieux vaut être sûr que désolé et utiliser une date réelle dans le passé.

si vous avez un contrôle sur la sortie du serveur, il serait préférable de ne pas ajouter d'en-têtes de mise en cache à la place.

3
répondu Brother Woodrow 2015-03-02 10:07:15

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;
}
3
répondu Felix 2015-06-18 00:47:27

ma solution était d'ajouter Cache-Control: no-cache en-tête sur le serveur, plus ajouter $templateCache.remove() avant de changer d'état. J'utilise angular-ui / ui-router. J'avais un problème avec IE11 et Edge browser.

$templateCache.remove('/partials/details.html');
$state.go('details');
2
répondu Hexadecy 2017-07-14 13:21:19

une solution évidente est d'utiliser des urls uniques. Mais comment le routeur url changé de poste d'initialisation Désactiver les caches de navigateur n'est pas une option, puisque nous en avons besoin pour les opérations normales. Vous pouvez supprimer les templates de $ templateCache quand ils ne sont pas plus nécessaire. ( http://docs.angularjs.org/api/ng .$ templateCache). Ces nouveaux fichiers sont ajoutés au cache dès que le téléchargement est terminé.

-3
répondu user1937163 2013-09-19 07:18:07