2017-09-05 70 views
24

我做了一个角网站,其中包含一个“添加”和“删除”的形式来处理数据对表在同一页上。角不更新缓存页面启用

当我测试它在本地或Chrome浏览器开发控制台(禁用缓存),当我添加一个新的项目或删除一个,该表将自动刷新本身。当我在客户端的生产服务器(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; 
    } 

我的猜测是,它要么是相关的一些服务器配置或给的WebPack代码。然而,我对后者并不熟悉,我只是把它留在了我使用的起始包上。

我创建a gist with the 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控制台并禁用了缓存,那么它会在不需要刷新的情况下更新它。

编辑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。我不会接受你必须放弃使用单页应用程序来实现这一功能的唯一原因。

+0

你可以从你的服务中显示你的'getProducts()'和'addProduct()'。另外,当你在组件中调用'addProduct'两次会发生什么? –

+0

更新了问题......无论多少次添加产品都无关紧要。该表保持不变,除非我打开开发控制台或清除缓存并刷新。 – Tasos

+0

这两个请求都被执行? –

回答

5

有特定的原因,没有的,你已经尝试过的事情有固定的东西。

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

接下来,你<meta>标签。通常,缓存控制由实际的http头完成。虽然你可以使用<meta>标签设置未在你的HTTP响应头指定的所有头,他们将那些已经被设置为不覆盖HTTP标头。IIS在响应头中有缓存的默认值,您的<meta>标签实际上不会做任何事情。当您通过file:///网址加载时,<meta>标签确实只能可靠地使用。

为了可靠地实现你想要做的事情,你需要真正让服务器发送你想要使用的缓存控制头。这可能会因您尝试支持哪些浏览器而有所不同,但由于您使用的是角度,因此我可能会认为您支持现代浏览器,这很简单。以下操作将禁用网站中所有静态文件的缓存,这可能是并不是您想要的,但可以作为指导。

<?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而不是使用静态.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}) 
+0

这不是一个asp.net网站。它只是一个Windows服务器 – Tasos

+0

第二部分(post())可以为你解决它。 –

+0

我在你的回复中添加了你想要的标题。 –

1

将一个带有全部时间标记或唯一标识的参数附加到您不想缓存的每个http调用。像冠军一样工作。我以前在Angular中使用模板时遇到了同样的问题。我只是添加了一个http拦截器,并为每个调用添加了一个时间戳,问题消失了。