在前端项目开发中,会遇到一种很奇怪的情况,就是在IE浏览器中get请求方式在初次请求之后不再进行请求了,而是会从缓存中获取数据,但是chrome浏览器会中却每次都会获取。
自然的想到一个问题,就是get存在缓存的问题!
- 起源:
常见的是ajax请求过一次以后,以后的相同url的get请求会存在下面这种情况:
- 第一种情况:有时返回304,有时返回200;
- 第二种情况:有时无论后台数据是否变化始终返回304,有时却始终返回200;同一套代码在不同浏览器间结果不同。
禁止浏览器缓存常用的方法:
- 在html页面设置Meta标签
<meta http-equiv="Cache-Control" content="no-store"/>
<meta http-equiv="Pragma" content="no-cache"/>
<meta http-equiv="Expires" content="0"/>
结果:因浏览器不同或者同一浏览器间版本不同,这个方法有很大的兼容性,很多时候根本没有作用。
- 在get请求的URL 参数后面加时间戳或者随机数
$.ajax({
url: 'http://localhost/api/list',
type: 'get',
data: {
_t: new Date().valueOf() //加时间戳
//_t: Math.random() 加随机数
},
success: function ( res ) {
console.log(res);
}
})
结果:这种方式虽然能解决IE始终返回304的问题,但实际上每个ajax都会去请求服务器,对web优化并非最佳的解决方案。
- 用post请求替代get请求
结果: 有其他方式解决现场尝试其他方式解决,一是因为这种做法不符合RESTful API设计,二是因为这种方式同样会每次请求服务器,可能会没有利用到浏览器自带的缓存功能,但是可以解决这个问题。
要实现的效果:
首次请求返回 200,数据不变的情况下,请求需和服务器确认返回 304,如果有数据变化,则返回 200,并且需要 IE和 google浏览器一致
先介绍一下浏览器的缓存机制:
前端需要在请求头中添加一下内容可以解决:
headers: {
//当只设置cacahe-control: 'no-cache'时,IE浏览器始终返回304,抓包工具抓不到包,请求不和服务器确认
//当只设置cacahe-control: 'no-cache'时,google浏览器始终返回200,抓包工具可以抓取包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能
'cache-control': 'no-cache',
//当只设置Pragma: 'no-cache'时,IE浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能
//当只设置Pragma: 'no-cache'时,google浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能
'Pragma': 'no-cache'
//两个参数同时不设置时,IE浏览器始终返回304,抓包工具抓不到包,请求不和服务器确认
//两个参数同时不设置时,google浏览器首次返回200,之后始终返回304,并且有和服务器确认
//两个参数同时设置时,IE浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能
//两个参数同时设置时,google浏览器始终返回200,抓包工具可以抓到所有包,请求重新从服务器获取数据,没有利用到浏览器的缓存功能
}
同时后端也要进行设置:
HttpServletResponse resp = (HttpServletResponse) servletResponse;
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Credentials", "true");
resp.setHeader("Access-Control-Allow-Methods","POST, GET, HEAD,PUT,OPTIONS, DELETE,PATCH");
resp.setHeader("Access-Control-Max-Age", "1800");
resp.setHeader("Access-Control-Allow-Headers","Origin, No-Cache, X-Requested-With, If-Modified-\
Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");