Лучший способ предотвратить кеш 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).
Эти новые добавляются в кеш, как только загрузка завершается.