1. 程式人生 > >IE瀏覽器中Get請求方式有快取的問題

IE瀏覽器中Get請求方式有快取的問題

在前端專案開發中,會遇到一種很奇怪的情況,就是在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"/>  
    

    結果:因瀏覽器不同或者同一瀏覽器間版本不同,這個方法有很大的相容性,很多時候根本沒有作用。

  2. 在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優化並非最佳的解決方案。

  3. 用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");