Лучший способ предотвратить кеш IE в AngularJS?

В настоящее время я использую ресурс service/$для создания ajax-вызовов (GET в этом случае), а IE кэширует вызовы, чтобы свежие данные не могли быть получены с сервера. Я использовал технику, которую я нашел при помощи Google, чтобы создать случайное число и добавить его в запрос, чтобы IE не перешел в кеш для данных.

Есть ли лучший способ, чем добавить cacheKill к каждому запросу?

factory code

.factory('UserDeviceService', function ($resource) {

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

Вызов с контроллера

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

Ответы

Ответ 1

Как запрошенный binarygiant, я отправляю свой комментарий в качестве ответа. Я решил эту проблему, добавив заголовки No-Cache к ответу на стороне сервера. Обратите внимание, что вы должны делать это только для запросов GET, другие запросы работают нормально.

binarygiant опубликовал, как вы можете это сделать на node/express. Вы можете сделать это в ASP.NET MVC следующим образом:

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

Ответ 2

Как описано в одном из моих других сообщений, вы можете отключить кеширование по всему миру в $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';
}]);

Ответ 3

Для тех, кто использует ASP.NET Web API 2, эквивалентное решение будет таким (Web API не использует ту же логику кэширования, что и 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;
            }
         }
    }
}

затем присоедините его в 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 }
    );
}

Ответ 4

Включение noCache в экземпляре является наилучшим способом для этого:

В node/express это работает, чтобы IE не кэшировал эти запросы:

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

Ответ 5

вы можете добавить перехватчик для генерации уникального URL-адреса запроса. Также вы можете удалить вызовы 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;
               }
           };
    });

Ответ 6

Я разрешаю это:

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

Ответ 7

Хотя этот подход:

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

Правильно, '0' не является допустимым значением для заголовка If-Modified-Since. Он должен быть действительной HTTP-датой, например:

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

Согласно spec:

Получатель ДОЛЖЕН игнорировать поле заголовка If-Modified-Since, если полученное значение поля не является допустимой HTTP-датой, или если запрос метод не является ни GET, ни HEAD.

Так что лучше быть в безопасности, чем жалеть, и использовать фактическую дату в прошлом.

Если у вас есть какой-либо контроль над выходом сервера, было бы предпочтительнее добавлять вместо этого заголовки кэширования.

Ответ 8

Коайский эквивалент бинарного ответа:

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

Ответ 9

Мое решение добавляло заголовок Cache-Control: no-cache на сервере плюс добавление $templateCache.remove() перед изменением состояния. Я использую angular -ui/ui-router. У меня возникла проблема с браузерами IE11 и Edge.

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

Ответ 10

Очевидным решением является использование уникальных URL-адресов. Но как изменить URL-адреса маршрутизатора после инициализации Отключение кэшей браузера не является вариантом, так как это необходимо для обычных операций. Вы можете удалить шаблоны из шаблона $templateCache, если нет более необходимо. (http://docs.angularjs.org/api/ng. $templateCache). Эти новые добавляются в кеш, как только загрузка завершается.