https://blog.csdn.net/playboyanta123/article/details/70313112javascript
一些瀏覽器中返回按鈕是直接使用緩存的,不會執行任何js代碼,例如, 在提交的時候將按鈕設置爲loading狀態,若是在提交成功後沒有對按鈕進行處理,那麼返回後按鈕依然是loading狀態,這就很尷尬了。html
緣由:部分瀏覽器在後退時不會觸發onload事件,這是HTML5世代瀏覽器新增的特性之一——Back-Forward Cache(簡稱bfcache)java
什麼是bfcacheweb
《JavaScript高級程序設計》有說起bfcache:瀏覽器
bfcache,即back-forward cache,可稱爲「往返緩存」,能夠在用戶使用瀏覽器的「後退」和「前進」按鈕時加快頁面的轉換速度。這個緩存不只保存頁面數據,緩存
還保存了DOM和JS的狀態,其實是將整個頁面都保存在內存裏。若是頁面位於bfcache中,那麼再次打開該頁面就不會觸發onload事件網絡
這個事件在頁面顯示時觸發,不管頁面是否來自bfcache。在從新加載的頁面中,pageshow會在load事件觸發後觸發;session
而對於bfcache中的頁面,pageshow會在頁面狀態徹底恢復的那一刻觸發。app
該事件會在瀏覽器卸載頁面的時候觸發,並且是在unload事件以前觸發。jsp
pageshow事件和pagehide事件的event對象還包含一個名爲persisted的布爾值屬性。
不一樣的瀏覽器在瀏覽器會在當前窗口「打開」歷史紀錄中的前一個頁面的表現上並不統一,這和瀏覽器的實現以及頁面自己的設置都有關係。
Firefox的開發者文檔中提供了一些思路:
1
2
3
4
5
|
window.addEventListener('pageshow', function( e ){
if (e.persisted) {
window.location.reload()
}
})
|
Safari、UC、qq瀏覽器測試經過。可是UC、qq瀏覽器會先閃過bfcache中的頁面,由於pageshow是在load事件觸發以後才觸發的。browser依然會保留紅色,我認爲是由於browser回到上頁時不觸發任何事件。
1
2
3
4
5
6
7
8
9
|
window.addEventListener('pagehide', function(e) {
var $body = $(document.body);
$body.children().remove();
// 要等到回調函數完成,用戶按返回才執行script標籤的代碼
setTimeout(
function() {
$body.append(
"<script type='text/javascript'>window.location.reload();<\/script>");
});
});
|
Safari、UC、qq瀏覽器測試經過。browser依然會保留紅色,我認爲是由於browser回到上頁時不觸發任何事件。
代碼示例以下:
在jsp模板的header部分加入以下的禁用緩存設置:
1
2
3
4
5
6
7
|
<head>
<%
response.setHeader("Cache-Control","no-cache,no-store,must-revalidate");
response.setHeader("Expires", "0");
response.setHeader("Pragma","no-cache");
%>
</head>
|
該方案的前提是瀏覽器在向server請求頁面時,每次都用jsp從新生成html。須要頁面自己有禁用緩存的配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<!-- 安卓webview 後退強制刷新解決方案 START -->
<jsp:useBean id="now" class="java.util.Date" />
<input type="hidden" id="SERVER_TIME" value="${now.getTime()}"/>
<script>
//每次webview從新打開H5首頁,就把server time記錄本地存儲
var SERVER_TIME = document.getElementById("SERVER_TIME");
var REMOTE_VER = SERVER_TIME && SERVER_TIME.value;
if(REMOTE_VER){
var LOCAL_VER = sessionStorage && sessionStorage.PAGEVERSION;
if(LOCAL_VER && parseInt(LOCAL_VER) >= parseInt(REMOTE_VER)){
//說明html是從本地緩存中讀取的
location.reload(
true);
}
else{
//說明html是從server端從新生成的,更新LOCAL_VER
sessionStorage.PAGEVERSION = REMOTE_VER;
}
}
</script>
<!-- 安卓webview 後退強制刷新解決方案 END -->
|
PC瀏覽器,設置禁用頁面緩存header便可實現後退刷新
支持bfcache/page cache的移動端瀏覽器,JS監聽pageshow/pagehide,在檢測到後退時強制刷新
在前2個方案都不work的狀況下,能夠在HTML中寫入服務端頁面生成版本號,與本地存儲中的版本號對比判斷是否發生了後退並使用緩存中的頁面