因缓存机制产生的数据实时性问题

问题描述:

项目和测试环境都存在门户换肤问题。

现象:

1、设置新的主题时,样式没有彻底换过来。

2、同一个浏览器上切换账号登陆门户后, 门户还是会使用之前登陆用户的主题样式。

 

 

图1.01 用户一登陆的主题样式

 

1.02 用户二登陆后的主题样式

问题分析:

1、浏览器的缓存机制:

一般浏览器都会存有自己的缓存,这是用户自己私有缓存。浏览器作为代理服务器,可以减少前端与服务器的一些不必要的交互,当数据没有更新的时候,浏览器就代替服务器返回上缓存的有的数据,提高了前端的响应速度。

当浏览器收到数据的请求时,http报文时,会对报文进行解析,并提取url和各种首部,然后查看缓存中是否有本地副本,如果没有就请求服务器获得副本,如果缓存中有副本的新鲜度过了,则会主动请求服务器看是否要更新,然后缓存变创建响应报文响应客户端,并记录下日志。

 

2、浏览器的缓存问题:

对于缓存,浏览器一个来自前端的请求的处理过程如下图所示:

 

图1.04 处理缓存的流程图

文本的新鲜度可以通过以下五种方式来定义缓存:

1.cache-control:no-store;

2.cache-control:no-chache;

3.cache-control:must-revalidate;

4.cache-contro:max-age;

5.附加Expires过期日期到响应中去。

也可以不加附加信息,让缓存自己确定文本副本的过期日期。

 

关于副本的验证,可以通过往报文中添加特殊的条件首部,而缓存验证的首部有If-Modified-Since:DateIf-None-Match:tags两种,If-Modified-Since:Date是指如果从指定日期之后文档被修改过了,就执行请求的方法,而If-None-Match:tags则是服务器为文档提供特殊的标签,类似序列号,当已缓存的标签和服务器文档中的标签有所不同,就会执行所请求的方法。在项目中用的方法是前者,如下图所示:

 

图1.03 home.css的请求

 

 

 

 

当在文本副本的有效期过后,浏览器会向服务器再核对文本的新鲜度,也就是上图1.03的服务器再验证,规则是上述说的If-Modified-Since:Date或者If-Modified-Since:Date。如果在服务器的文本内容没有改变,则会返回304响应,并对新鲜度进行更新。如果改变了则返回带有新文本内容的200响应,并将文本内容放入缓存中提供给客户端。在项目中,由于缓存的是一开始的登陆者的样式缓存,换了登陆者时,这时候浏览器进行再验证的时候,由于验证的文本是缓存中的上一个登陆者的验证文本,而在服务器中此写文本是没有改变的,因此服务器返回的响应时304响应,如下图所示:

 

         

 

所以浏览器会一直用之前上个登陆者用的样式文件缓存,所以才有主题用的还是之前的样式的问题。因此我们需要在登陆加载到主页面的时候,强制绕过浏览器缓存直接请求服务器刷新文本数据,同时也更新服务器缓存的副本。

 

问题解决方案:

思路:利用window.location.reload(true)方法,绕过浏览器缓存,强制向服务器请求样式

做法:在home.jsp中内嵌iframe用于强制刷新样式文件

$(window).load(function() {

 $("#loadCssFrame").contentWindow.location.reload(true);

});

好处:在需要的时候,刷新样式文件,在业务系统操作界面上,不需要加载样式文件

缺点:在home.jsp会加载多余的样式文件

 

你可能感兴趣的:(因缓存机制产生的数据实时性问题)