瀏覽器往返緩存--back-forward cache(bfcache)
什么是 bfcache
?
bfcache
,即 back-forward cache
,可稱為往返緩存,可以在用戶使用瀏覽器的 后退 和 前進 按鈕時加快頁面的轉換速度。這個緩存不僅保存頁面數據,還保存了 DOM
和 JS
的狀態,實際上是將整個頁面都保存在內存里。如果頁面位於bfcache中,那么再次打開該頁面就不會觸發 onload
事件。這是 HTML5 世代瀏覽器新增的特性之一。
這就產生了一個問題,如果希望用戶每次打開這個頁面的時候都能夠獲取到最新的資源,因為 bfcache
的存在,不做特殊的處理這個效果就無法達到。
解決方案
- 監聽
pageshow
事件,若頁面是來自bfcache
,則對頁面進行刷新:
window.addEventListener('pageshow', function (e) {
if (e.persisted) {
window.location.reload()
}
})
- 監聽
pagehide
事件阻止頁面進入bfcache
:
window.addEventListener('pagehide', function (e) {
var dom = document.body;
dom.children.remove();
setTimeout(function () {
dom.appendChild("<script type='text/javascript'>window.location.reload();<\/script>");
});
});
pageshow
事件
pageshow
事件在頁面呈現的時候觸發, 類似於 onload
事件,但是 onload
事件是在文檔加載完畢的時候觸發,如果頁面是從瀏覽器緩存中讀取時不會觸發; pageshow 事件則是在每次加載頁面時都觸發。
pagehide
事件
該事件會在用戶離開頁面時觸發。離開頁面有多種方式。如點擊一個跳轉鏈接,刷新頁面,提交表單,關閉瀏覽器等。pagehide
事件與 unload
事件 unload類似,但是如果離開頁面時頁面進入了緩存則不會觸發 unload
事件, 同理,unload
事件觸發后無法緩存頁面。
persisted
屬性
pageshow
事件和 pagehide
事件的 event
對象還包含一個名為 persisted
的布爾值屬性。對於 pageshow
事件,如果頁面是從 bfcache
中加載的,則這個屬性的值為true;否則,這個屬性的值為false。對於 pagehide
事件,退出頁面之后,如果頁面被保存在 bfcache
中,則這個屬性的值為true;否則,這個屬性的值為false。
不同的瀏覽器在對當前窗口‘打開’歷史記錄中的前一個頁面的表現上並不統一,這和瀏覽器的實現以及頁面本身的設置有關系。
- 設置
meta
標簽,清除頁面緩存:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
Cache-Control
指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置 Cache-Control
並不會修改另一個消息處理過程中的緩存處理過程。請求時的緩存指令包括 no-cache
、no-store
、max-age
、max-stale
、min-fresh
、only-if-cached
,響應消息中的指令包括 public
、private
、no-cache
、no-store
、no-transform
、must-revalidate
、proxy-revalidate
、max-age
。各個消息中的指令含義如下
Public
: 指示響應可被任何緩存區緩存;Private
: 指示對於單個用戶的整個或部分響應消息,不能被共享緩存處理。這允許服務器僅僅描述當用戶的部分響應消息,此響應消息對於其他用戶的請求無效no-cache
: 指示請求或響應消息不能緩存no-store
: 用於防止重要的信息被無意的發布。在請求消息中發送將使得請求和響應消息都不使用緩存。max-age
: 指示客戶機可以接收生存期不大於指定時間(以秒為單位)的響應min-fresh
: 指示客戶機可以接收響應時間小於當前時間加上指定時間的響應max-stale
: 指示客戶機可以接收超出超時期間的響應消息。如果指定max-stale消息的值,那么客戶機可以接收超出超時期指定值之內的響應消息。