Угловая проблема кэширования IE для $ http

256

Все вызовы ajax, отправленные из IE, кэшируются Angular, и я получаю 304 response для всех последующих вызовов. Хотя запрос тот же, ответ не будет таким же в моем случае. Я хочу отключить этот кеш. Я попытался добавить cache attribute в $http.get, но все равно он не помог. Как решить эту проблему?

Теги:
caching

17 ответов

429
Лучший ответ

Вместо отключения кэширования для каждого отдельного запроса GET я отключу его глобально в $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';
}]);
  • 78
    Заголовок If-Modified-Since заставляет IIS + ngInclude ngView ngInclude ngView запросов для каждого html-файла, загруженного через ngInclude и ngView . Следующие два заголовка исправили эту проблему для меня (я вытащил их из Chrome, у которого не было проблемы с кэшированием): $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache'; $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
  • 0
    Отлично. Это работало там, где добавление уникальной строки запроса не выполнялось. Для тех, кто читает это, попробуйте это раньше, чем позже, и сэкономьте себе время.
Показать ещё 18 комментариев
65

Вы можете либо добавить уникальную строку запроса (я считаю, что это то, что jQuery делает с параметром cache: false) для запроса.

$http({
    url: '...',
    params: { 'foobar': new Date().getTime() }
})

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

  • 2
    $http.get(url+ "?"+new Date().toString()) - это просто другое представление, без использования параметра, но с добавлением его в строку запроса.
27

вы можете добавить перехватчик.

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

вы должны удалить строки console.log после проверки.

  • 0
    И вы должны использовать $log на тот случай, если вы забудете их убрать.
  • 2
    У меня серьезные проблемы с кэшированием в IE, что приводит к пустой странице, потому что важные части не выполняются. Использование этого перехватчика решило эту проблему! +1
Показать ещё 2 комментария
14

Я просто добавил три метатега в index.html в проекте angular, и проблема с кешем была решена в 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">
  • 2
    Мы уже имели эти метатеги в нашем index.html когда заметили, что IE11 кэширует AJAX-запросы: / Но настройка $httpProvider как показано в других ответах, работала нормально.
12

Дублирование моего ответа в другом потоке.

Для Углового 2 и более нового - самый простой способ добавить заголовки no-cache, переопределяя RequestOptions:

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

И ссылайтесь на него в своем модуле:

@NgModule({
    ...
    providers: [
        ...
        { provide: RequestOptions, useClass: CustomRequestOptions }
    ]
})
  • 0
    Разве это не заголовки для ответа сервера, а не для запроса браузера? (Я мог бы представить, что можно установить If-Modified-Since с некоторой датой в далеком прошлом, используя вышеописанный метод.)
  • 0
    @Vitaliy: - Почему эта проблема возникает с угловой и т. Е.?
Показать ещё 1 комментарий
9

Гарантированным, что я работал, было что-то в этом роде:

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

Я должен был объединить 2 из вышеперечисленных решений, чтобы гарантировать правильное использование для всех методов, но вы можете заменить common с помощью get или другого метода, то есть put, post, delete чтобы сделать эту работу для разных случаев.

  • 0
    Можете ли вы сказать мне, где в коде вы добавили это в файл angular.js? какая строка #?
  • 0
    @JonathanScialpi Я обновил это, чтобы показать, где я мог бы поместить это. Где это находится внутри анонимной функции, не должно иметь значения.
Показать ещё 4 комментария
7

Эта строка помогла мне (Angular 1.4.8):

$httpProvider.defaults.headers.common['Pragma'] = 'no-cache';

UPD: Проблема заключается в том, что IE11 делает агрессивное кэширование. Когда я смотрел на Fiddler, я заметил, что в режиме F12 запросы отправляют "Pragma = no-cache", и конечная точка запрашивается каждый раз, когда я посещаю страницу. Но в нормальном режиме конечная точка была запрошена только один раз в первый раз, когда я посетил страницу.

  • 1
    Только к вашему сведению, этот ответ вызвал проблему CORS при запросе файлов из хранилища BLOB-объектов Azure, которую было сложно отследить, но в конце концов выяснили, что это было причиной. Удаление заголовка прагмы устранило мою проблему с CORS (но вновь установила проблему с кэшированием в IE).
6

Чтобы избежать кэширования, один из вариантов заключается в предоставлении другого URL-адреса для одного и того же ресурса или данных. Чтобы создать другой URL-адрес, вы можете добавить строку случайного запроса в конец URL-адреса. Этот метод работает для JQuery, Angular или других запросов ajax другого типа.

myURL = myURL +"?random="+new Date().getTime();
6

Я решил разрешить добавление даты и времени как случайное число:

$http.get("/your_url?rnd="+new Date().getTime()).success(function(data, status, headers, config) {
    console.log('your get response is new!!!');
});
  • 0
    : - Почему эта проблема возникает с угловатыми и т.е?
4

Решение выше будет работать (сделать URL уникальным, добавив в querystring новый параметр), но я предпочитаю, чтобы решение предлагало [здесь]: Лучший способ предотвратить IE-кеш в AngularJS?, которые обрабатывают это на уровне сервера, поскольку это не относится к IE. Я имею в виду, что если этот ресурс не должен кэшироваться, сделайте это на сервере (это не имеет никакого отношения к используемому браузеру, это не противоречит ресурсу).

Например, в java с JAX-RS выполните программно для JAX-RS v1 или declativly для JAX-RS v2.

Я уверен, что кто-нибудь поймет, как это сделать

  • 1
    Хотя это может быть разработано, это правильный способ сделать это. Клиентская сторона не должна выбирать, что кэшировать или нет, но именно сервер должен сообщать клиенту, что нужно кэшировать или нет.
  • 0
    Я полностью согласен, это должен быть правильный путь
1

также вы можете попробовать в своем сервисе установить заголовки, например, например:

...
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")                   
    }
}
....
1

Это немного до старости, но: Решения вроде устарели. Пусть сервер обрабатывает кеш или не кэширует (в ответе). Единственный способ гарантировать отсутствие кеширования (думать о новых версиях в производстве) - это изменить файл js или css с номером версии. Я делаю это с помощью webpack.

1

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

Для ленивых - это решение:

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

Всегда использовать простой подход добавить временную метку с каждым запросом не нужно очищать кеш

    let c=new Date().getTime();
    $http.get('url?d='+c)
0
meta http-equiv="Cache-Control" content="no-cache"

Я просто добавил это в View и начал работать над IE. Подтверждено работать на Angular 2.

0

Эта проблема связана с проблемой кэширования IE, как вы сказали, вы можете протестировать ее в режиме отладки IE, нажав f12 (это будет отлично работать в режиме отладки).IE не будет принимать данные сервера каждый раз, когда вызовы страницы, он берет данные из кеша. Чтобы отключить это, выполните одно из следующих действий:

  • добавьте следующее с URL-адресом запроса http-сервиса

//До (выдается один)

this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + engagementName, {})

//После (отлично работает)

this.httpService.get(this.serviceUrl + "/eAMobileService.svc/ValidateEngagmentName/" + engagementName + "? DateTime =" + new Date(). getTime() + '', {cache: false })

  1. отключить кеш для всего модуля: -

$httpProvider.defaults.headers.common ['Pragma'] = 'no-cache';

-2

Попробуйте это, это сработало для меня в одном случае:

$http.get("your api url", {
headers: {
    'If-Modified-Since': '0',
    "Pragma": "no-cache",
    "Expires": -1,
    "Cache-Control": "no-cache, no-store, must-revalidate"
 }
})

Ещё вопросы

Сообщество Overcoder
Наверх
Меню