Подтвердить что ты не робот

Angular не обновляет страницу с включенным кешем

Я создал веб-сайт angular, который содержит форму "добавить" и "удалить", чтобы манипулировать данными в таблице на той же странице.

Когда я тестирую его локально или с помощью Chrome Dev Console (отключенный кеш), когда я добавляю новый элемент или удаляю его, таблица автоматически обновляется. Когда я тестирую его на сервере производства (IIS Server) моего клиента, он работает только с консолью Chrome Dev Console. В противном случае они должны использовать CTRL + F5 для обновления кеша и отображения изменений на странице.

Это код компонентов:

  addProduct() {
    this._productsService.addProduct(this.addFormProductItem)
      .subscribe(v => {
        this._productsService.getProducts().subscribe( 
          products => {this.products = products, this.onChangeTable(this.config)}
      );
    });
    this.addmodalWindow.hide();
    return;
  } 


  onChangeTable(config: any, page: any = {
    page: this.page,
    itemsPerPage: this.itemsPerPage
  }): any {
    if (config.filtering) {
      Object.assign(this.config.filtering, config.filtering);
    }
    if (config.sorting) {
      Object.assign(this.config.sorting, config.sorting);
    }
    this.ng2TableData = this.products;
    this.length = this.ng2TableData.length;
    let filteredData = this.changeFilter(this.ng2TableData, this.config);
    let sortedData = this.changeSort(filteredData, this.config);
    this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;
    this.length = sortedData.length;
  }

Я предполагаю, что это связано либо с конфигурацией сервера, либо с кодом webpack. Тем не менее, я не знаком с последним, и я просто оставил его, как это было в исходном пакете, который я использовал.

Я создал сущность с веб-пакетом, так как это длинный файл

Изменить 1: После некоторых дополнительных исследований я попытался добавить следующее в файл web.config в корневую папку приложения.

<caching enabled="false" enableKernelCache="false">
      <profiles>
         <add extension=".css" policy="DontCache" kernelCachePolicy="DontCache" />
         <add extension=".html" policy="DontCache" kernelCachePolicy="DontCache" />
         <add extension=".js" policy="DontCache" kernelCachePolicy="DontCache" />
      </profiles>
</caching>

Тем не менее, у меня все еще такое же поведение. Добавление элемента с закрытой консолью Dev Console не обновляет таблицу. Но если у меня консоль dev открыта и отключена кеш, то она обновляет ее без необходимости обновления.

Изменить 2: Работа с окном инкогнито не устраняет проблему.

Изменить 3: Добавление метатег в index.html еще не исправляет проблему.

<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">

Изменить 4:

  getProducts() {
    return this._http.get(this.API + '/products/all')
      .map((response: Response) => <Product[]>response.json().products);
  }

  addProduct(product:Product) {
    if ( this._loggedInGuard.isLoggedIn() ) {
      let token = localStorage.getItem('my.token');
      let body = JSON.stringify(product);
      let headers = new Headers(
         { 'Content-Type': 'application/json',
         'Authorization': 'Bearer ' + token});
      return this._http
      .post(this.API + "/products/store", body, {headers: headers} )
      .map(res => res.json())
      .catch(this._responseService.catchBadResponse)
      .do(() => this._responseService.success('Success. You added a product!'));

    }  
  }

Изменить 5

Единственное решение, которое я могу найти, - это перезагрузить окно каждый раз, когда я обновляю данные с помощью location.reload(true). Но опять же, это работает только на Firefox, а не на Chrome. И я не буду признавать, что вам нужно отказаться от единственной причины иметь одностраничное приложение, чтобы это сработало.

4b9b3361

Ответ 1

Есть определенные причины, по которым ни одна из вещей, которые вы пробовали, не зафиксировала.

Прежде всего, использование элемента <caching> в web.config не указывает браузеру, как кэшировать ответ. Он используется для настройки того, как сервер IIS кэширует ответ, чтобы он мог быть повторно использован в будущих запросах. Здесь - это документация, которая объясняет это.

Далее, тэги <meta>. Обычно управление кешем выполняется с помощью фактических заголовков HTTP. Хотя вы можете использовать теги <meta> для установки заголовков, которые вообще не указаны в вашем заголовке ответа HTTP, они НЕ будут переопределять заголовки HTTP, которые уже установлены. IIS имеет значения по умолчанию для кэширования в заголовках ответов, тэги <meta> на самом деле ничего не сделают. Теги <meta> действительно полезны только при загрузке по URL file:///.

Чтобы надежно достичь того, что вы пытаетесь сделать, вам нужно фактически заставить сервер отправлять заголовки управления кешем, которые вы хотите использовать. Это может варьироваться в зависимости от того, какие браузеры вы хотите поддерживать, но поскольку вы используете angular, я могу предположить, что вы поддерживаете современные браузеры, что просто. Следующее отключит кеширование для ВСЕХ статических файлов на вашем веб-сайте, что, вероятно, не совсем то, что вы хотите, но может служить в качестве руководства.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <location path=".">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="DisableCache" />
      </staticContent>
    </system.webServer>
  </location>
</configuration>

Однако, первое, что вам нужно сделать, - изучить текущие заголовки ответов, которые IIS отправляет вам! Это можно сделать легко с помощью инструментов разработчиков Chrome. Если вы видите заголовок Cache-Control: в ответе, это подтвердит мои рассуждения о том, почему тэги <meta> не работают.

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

Response.Cache.SetCacheability(HttpCacheability.NoCache);

Если вы хотите поддерживать гораздо более старые или взломанные браузеры, есть другие ресурсы, которые описывают, какие дополнительные заголовки вам нужно добавить, что снова можно сделать с помощью кода web.config или ASP.NET. Я просто хочу повторить повтор: если у вас все еще есть проблемы, убедитесь, что вы просматриваете заголовки ответов, отправленные сервером.

Ответ 2

Для страниц ASP.NET вы не хотите кэшировать нигде,

HttpContext.Current.Response.Cache.SetCacheability
                            (HttpCacheability.Server);
HttpContext.Current.Response.Cache.SetNoStore();
Response.Cache.SetExpires(DateTime.Now); 
Response.Cache.SetValidUntilExpires(true); 

Это указывает всем кэширующим прокси-серверам, что только серверу разрешено кэшировать страницу и сообщает серверу не кэшировать его. Последние две строки кода просят браузер не кэшировать его. Приведенный выше код приводит к этим трем заголовкам:

 Cache-Control:no-cache, no-store
 Pragma:no-cache
 Expires:-1

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

.post(this.API + "/products/store?unique=milliseconds", body, {headers: headers} )

Ответ 3

Добавить параметр с полной меткой времени или уникальный идентификатор для каждого HTTP-вызова, который вы не хотите кэшировать. Работает как чемпион. Я использовал ту же проблему, используя шаблоны в Angular. Я просто добавил http-перехватчик и добавил временную метку для каждого вызова, и проблема исчезла.