Проблема углового кэширования, т. е. за $протоколу HTTP



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

91   17  

17 ответов:

вместо отключения кэширования для каждого отдельного 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';
}]);

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

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

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

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

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

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

Я просто добавил три мета-тега в индекс.html на угловом проекте, и проблема кэша была решена на 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 и новее, самый простой способ добавить упомянутые заголовки-переопределить RequestOptions класс, используемый Http сервис:

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

гарантированный, что я работал, был чем-то вроде этих строк:

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 чтобы сделать эту работу для различных случаев.

эта единственная строка помогла мне (угловой 1.4.8):

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

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

Я получаю это решение, добавляя datetime как случайное число:

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

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

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

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

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

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

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

для ленивых вот решение:

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

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

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

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

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

  1. добавьте следующее с вашим url-адресом запроса Службы http

/ / раньше (выдал один)

этого.служба HTTPService.получить это.serviceUrl + "/eAMobileService.svc / ValidateEngagmentName/ " + engagementName, {})

//После (работает нормально)

этого.служба HTTPService.получить это.serviceUrl + " / eAMobileService.svc / ValidateEngagmentName/ " + engagementName +"?DateTime= " + новая дата ().getTime ()+", { cache: false })

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

$httpProvider.по умолчанию.заголовки.common ['Pragma'] = 'no-cache';

meta http-equiv="Cache-Control" content="no-cache"

Я просто добавил Это для просмотра, и он начал работать на IE. Подтверждена работа на угловой 2.

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

    let c=new Date().getTime();
    $http.get('url?d='+c)

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

$http.get("your api url", {
headers: {
    'If-Modified-Since': '0',
    "Pragma": "no-cache",
    "Expires": -1,
    "Cache-Control": "no-cache, no-store, must-revalidate"
 }
})
    Ничего не найдено.

Добавить ответ:
Отменить.