angular js 在ie11 下的get請求緩存問題的解決辦法


使用angularjs 1.x開發的應用在ie11 下回碰到各種怪異的情況:一般表現在:

還有另外一種情況,就是:get請求被緩存,導致頁面數據沒有刷新。今天我們就來解決這個問題。

幾行代碼:


myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }    

    // Answer edited to include suggestions from comments
    // because previous version of code introduced browser-related errors

    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);

相信您的問題已經解決了,下面我整理了一點關於rest 緩存方面的東西。 看完之后應該能加明白代碼的含義。


創建可緩存的內容

  • GET請求的響應默認是可以緩存的(響應應該包含一個到期時間, 或者有一個驗證器)
  • POST請求的響應默認是不可以緩存的, 但如果響應頭中包含明確允許的Expires頭或者Cache-Control頭信息, 那么它還是可以緩存的.
  • PUT和DELETE請求的響應總是不可緩存的

為緩存使用響應頭信息有兩種主要的HTTP響應頭可以控制緩存的行為:

  • Expires

為一個緩存的表述指定絕對時間. 過了這個時間, 就認為被緩存的表述是過期的, 必須經過來源服務器的重新驗證.服務要聲明某個表述已經過期, 可以將Expires值設置成和Date頭信息的值相等(這個表述現在就回到期), 或者將Expires設置為0.
如果要使一個表述"永不到期", 服務可以設置Expires值為一年后.

  • Cache-Control

可以用在請求和響應上, 以控制響應的緩存行為. 這個頭信息的值由一個或者多個逗號分隔的指令組成. 這些指令決定了響應是否可以緩存, 如果可以, 那么由誰緩存, 緩存多長時間.

如何使用Expires和Cache-Control?

  • 如果我們可以確定一個被緩存響應的絕對到期時間, 就可以使用Expires頭.

  • 如果指明響應離開來源服務器后還能保持多久有效更合適的話, 就應該使用Cache-Control, 它增加了一個max-age或者s-maxage指令以指定一個相對的生存時間(Time to Live, TTL)

可緩存的響應(無論來自GET還是POST)都應該包含一個驗證器--ETag或者Last-Modified頭信息:

  • ETag

一個ETag值是一個不透明的字符串, 服務器將它與資源相關聯, 以便在資源的生命周期中唯一標示其狀態. 當資源發生變化時, 實體值也響應發生變化. ETag值不僅可以用來做並發控制, 而且在驗證被緩存資源的新鮮度(freshness)方面也同樣有用.

  • Last-Modified

一個響應的Date信息表示響應是何時生成的, Last-Modified頭信息表示相關聯資源是在何時修改的. Last-Modified不能晚於Date.

究竟是選擇ETag還是Last-Modified, 應該根據資源更新的頻率決定. Last-Modified的准確度僅僅與時間戳(精確到秒)相同, 而ETag能以任意頻率生成. 但是通常生成時間戳的開銷較小.
在響應中使用緩存指令當被用在響應中時, Cache-Control指令有3個功能:

  • 一些指令要求將通常不可緩存的響應緩存起來
  • 另一些指令要求不將通常可以緩存的響應緩存起來
  • 剩下的指令完全不影響一個響應是否緩存起來,它們只是用來確定已經緩存起來的響應的新鮮度.

一個單獨的Cache-Control指令可以具有以下一個或者多個功能!
具體的Cache-Control指令列表:

  • max-age=${delat-seconds}

該指令可以同時控制可緩存性和新鮮度. 它使用本地緩存和共享緩存(代理緩存和反向代理緩存)將一個響應緩存起來, 並且以秒為單位制定其保鮮壽命. 一個max-age值會覆蓋響應中的任何Expires值.

  • s-maxage={delta-seconds}

和max-age一樣, 這條指令有2個功能: 它使響應緩存起來, 但只能由共享緩存來做這件事, 並且以秒為單位指定了其保鮮壽命

  • public

這個指令使本地緩存或者共享緩存將一個響應緩存起來, 但它沒有指定一個新鮮度值. 重要的是, public優先於Authorization頭信息. 一般來說, 如果一個請求包含一個Authorization頭信息, 那么響應不會被緩存, 但設置了public指令的響應例外. 但緩存需要身份認證的響應時, 你應該謹慎.

  • private

這個指令使一個響應被緩存, 但只能在本地緩存(在瀏覽器或者其他客戶端). 它可以防止共享緩存將通常可以緩存的響應緩存起來. private不指定新鮮度值.

  • must-revalidate

這個指令使通常不可緩存的響應緩存起來,但需要緩存重新到來源服務器上驗證一下過期的響應. 只有當過期的響應成功通過來源服務器的驗證,緩存的內容才可以被用於滿足需求.
must-revalidate指令在平衡一致性(consistency)方面非常有用,可以減少帶寬和計算資源的消耗. 雖然它強制要求到來源服務器上重新驗證請求,但一種服務器端有效的驗證機制能阻止核心服務邏輯被請求重復調用,而開銷僅僅是生成一些304 Not Modified響應.

  • proxy-revalidate

除了只適用於共享緩存外, 這個指令和must-revalidate相同

  • no-cache

這個指令要求緩存為每個請求都到來源服務器上重新驗證已緩存的響應. 如果請求通過驗證, 則緩存的內容可以使用.
這個指令僅適用於已經被其他頭信息或者指令設置為可緩存的情況(即它不能使可以緩存的響應不被緩存)
不幸的是, 不同的緩存對於no-cache有不同的行為,一些緩存將no-cache作為一個不緩存響應的指令.

  • no-store

這個指令使得所有緩存(包括本地緩存, 代理緩存, 反向代碼緩存)不將可以被緩存的內容緩存起來.
HTTP Stale Controls Information RFC最近增加了2條新的指令:

  • stale-while-revalidate={delta-seconds}

在緩存能夠發布(release)一個過期的被緩存響應的情況下,這條指令允許緩存立刻發布響應,同時它也指示緩存在后台(即以非阻塞的方式)重新驗證被緩存響應.
這條指令以犧牲一致性為代價,減少了延遲(緩存立即發布過期的響應,同時重新驗證它).如果一個過期的表述沒有在delta-seconds(指定的秒數)之前完成重新驗證, 那么緩存會放棄使用它.

  • stale-if-error={delta-seconds}

該指令允許一個緩存在聯系來源服務器發生錯誤時發布一個過期的緩存響應. 如果一個被緩存響應比delta-seconds指定的時間范圍更舊, 那么就不應該發布它. 這條指令以犧牲一致性為代價, 提供了可用性.

栗子

  • 使緩存的內容僅存在於本地緩存, 時間為1個小時
  1. Cache-Control: private, max-age=3600
  • 緩存身份認證后的響應
  1. Cache-Control: public, max-age=0

public使得響應能被本地緩存和共享緩存緩存住,但max-age=0需要在發布被緩存表述前去到源服務器上重新驗證(使用一個條件GET). (理想情況下, 我們使用no-cache,但是由於一些緩存將no-cache當成了完全不緩存指令處理,所以選擇max-age=0代替).
當我們想要為每個請求授權,同時又希望通過緩存基礎設施提供響應以節省帶寬時, 這個組合非常有用的.
當到服務器上重新驗證每個請求時,緩存會將消費者提供的Authorization頭信息內容傳遞到服務器,如果來源服務器返回了401,表示未通過認證,緩存將不會發布被緩存的表述. 這個public,max-age=0組合不同於must-revalidate的地方,就是它允許緩存那些包含Authorization頭信息的請求對象的響應.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM