Angular不会在启用缓存的情况下更新页面

Tas*_*sos 25 iis caching webpack angular

我创建了一个有角度的网站,其中包含一个"添加"和一个"删除"表单来操作同一页面上的表格上的数据.

当我在本地或使用Chrome Dev Console(禁用缓存)进行测试时,当我添加新项目或删除新项目时,该表格会自动刷新.当我在客户端的生产服务器(IIS服务器)上测试它时,它仅适用于打开的Chrome开发者控制台.否则,他们必须使用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;
  }
Run Code Online (Sandbox Code Playgroud)

我的猜测是它与某些服务器配置或webpack代码有关.但是,我对后者并不熟悉,我只是把它留在了我使用的起始包装上.

用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>
Run Code Online (Sandbox Code Playgroud)

但是,我仍然有相同的行为.在Dev Console关闭的情况下添加项目,它不会更新表格.但是如果我打开了开发控制台并禁用了缓存,那么它就会更新它而无需刷新.

编辑2:使用隐身窗口无法解决问题.

编辑3:在index.html上添加元标记并不能解决问题.

<meta http-equiv="Cache-control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
Run Code Online (Sandbox Code Playgroud)

编辑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!'));

    }  
  }
Run Code Online (Sandbox Code Playgroud)

编辑5

我能找到的唯一解决方案是每次使用数据更新时重新加载窗口location.reload(true).但同样,这仅适用于Firefox,而不适用于Chrome.我不会接受你必须放弃使用单页应用程序来实现这项工作的唯一原因.

Avi*_*rry 6

有一些具体的原因,你所尝试的东西都没有固定的东西.

首先,使用<caching>web.config中的元素不会指示浏览器如何缓存响应.它用于配置IIS 服务器如何缓存响应,以便在将来的请求中重用它.以下是解释该文档的文档.

接下来,你的<meta>标签.通常,缓存控制由实际的http标头完成.虽然您可以使用<meta>标记来设置http响应标头中未指定的标头,但它们不会覆盖已设置的http标头.IIS在响应标头中具有缓存的默认值,您的<meta>标签实际上不会执行任何操作.<meta>当你加载一个file:///url 时,标签实际上只是非常有用.

为了可靠地实现您要执行的操作,您需要实际让服务器发送您要使用的缓存控制头.这取决于您尝试支持的浏览器,但由于您使用的是角度,我可能会认为您支持现代浏览器,这很简单.以下将禁用您网站中所有静态文件的缓存,这可能不是您想要的,但可以作为指南.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <location path=".">
    <system.webServer>
      <staticContent>
        <clientCache cacheControlMode="DisableCache" />
      </staticContent>
    </system.webServer>
  </location>
</configuration>
Run Code Online (Sandbox Code Playgroud)

但是,您应该做的第一件事是检查IIS发送给您的当前响应标头!使用Chrome开发人员工具可以轻松完成此操作.如果您Cache-Control:在响应中看到标题,这将确认我为什么您的<meta>代码无效的原因.

如果您为角度应用程序生成HTML而不是使用静态.html文件,而是使用ASP.NET生成它,那么最好的办法是在控制器中添加设置缓存头的代码.

Response.Cache.SetCacheability(HttpCacheability.NoCache);
Run Code Online (Sandbox Code Playgroud)

如果您想支持更旧或更糟的浏览器,那么还有其他资源可以描述您需要添加的额外标头,这也可以使用web.config或ASP.NET代码完成.我只想重新迭代:如果您仍然遇到问题,请确保您正在查看服务器发送的响应标头.