在前端项目开发中,会遇到一种很奇怪的情况,就是在IE浏览器中get请求方式在初次请求之后不再进行请求了,而是会从缓存中获取数据,但是chrome浏览器会中却每次都会获取。

自然的想到一个问题,就是get存在缓存的问题!

  • 起源:

常见的是ajax请求过一次以后,以后的相同url的get请求会存在下面这种情况:

  • 第一种情况:有时返回304,有时返回200;
  • 第二种情况:有时无论后台数据是否变化始终返回304,有时却始终返回200;同一套代码在不同浏览器间结果不同。
禁止浏览器缓存常用的方法:
  1. 在html页面设置Meta标签
<meta http-equiv="Cache-Control" content="no-store"/>  
<meta http-equiv="Pragma" content="no-cache"/>  
<meta http-equiv="Expires" content="0"/>

结果:因浏览器不同或者同一浏览器间版本不同,这个方法有很大的兼容性,很多时候根本没有作用。

  1. 在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优化并非最佳的解决方案。

  1. 用post请求替代get请求
    结果: 有其他方式解决现场尝试其他方式解决,一是因为这种做法不符合RESTful API设计,二是因为这种方式同样会每次请求服务器,可能会没有利用到浏览器自带的缓存功能,但是可以解决这个问题。

要实现的效果:

首次请求返回 200,数据不变的情况下,请求需和服务器确认返回 304,如果有数据变化,则返回 200,并且需要 IE和 google浏览器一致

先介绍一下浏览器的缓存机制:


浏览器请求本地起的springboot项目 浏览器请求方式有_服务器



前端需要在请求头中添加一下内容可以解决:

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");