解決手機上頁面返回但是頁面js沒有重新整理的痛點

來源:互聯網
上載者:User

標籤:exp   恢複   window   The   並且   bfc   儲存   原因   ever   

70313112

一些瀏覽器中返回按鈕是直接使用緩衝的,不會執行任何js代碼,例如, 在提交的時候將按鈕設定為loading狀態,如果在提交成功後沒有對按鈕進行處理,那麼返回後按鈕依然是loading狀態,這就很尷尬了。

原因:部分瀏覽器在後退時不會觸發onload事件,這是HTML5世代瀏覽器新增的特性之一——Back-Forward Cache(簡稱bfcache)

什麼是bfcache

《JavaScript進階程式設計》有提及bfcache:

bfcache,即back-forward cache,可稱為“往返緩衝”,可以在使用者使用瀏覽器的“後退”和“前進”按鈕時加快頁面的轉換速度。這個緩衝不僅儲存頁面資料,

還儲存了DOM和JS的狀態,實際上是將整個頁面都儲存在記憶體裡。如果頁面位於bfcache中,那麼再次開啟該頁面就不會觸發onload事件

pageshow事件

這個事件在頁面顯示時觸發,無論頁面是否來自bfcache。在重新載入的頁面中,pageshow會在load事件觸發後觸發;

而對於bfcache中的頁面,pageshow會在頁面狀態完全恢複的那一刻觸發。

pagehide事件

該事件會在瀏覽器卸載頁面的時候觸發,而且是在unload事件之前觸發。

persisted屬性

pageshow事件和pagehide事件的event對象還包含一個名為persisted的布爾值屬性。

  • 對於pageshow事件,如果頁面是從bfcache中載入的,則這個屬性的值為true;否則,這個屬性的值為false。
  • 對於pagehide事件,如果頁面在卸載之後被儲存在bfcache中,則這個屬性的值為true;否則,這個屬性的值為false。

不同的瀏覽器在瀏覽器會在當前視窗“開啟”曆史紀錄中的前一個頁面的表現上並不統一,這和瀏覽器的實現以及頁面本身的設定都有關係。

 

解決方案

 

Firefox的開發人員文檔中提供了一些思路:

  • 頁面監聽了 unload 或者 beforeunload 事件;
  • 版面設定了 “cache-control: no-store”.
  • 網站使用 HTTPS 同時頁面至少滿足以下一個條件:
    • “Cache-Control: no-cache”
    • “Pragma: no-cache”
    • 佈建要求頭 “Expires: 0” 或者 “Expires” 的值為 “Date” 之前的值 (除非 “Cache-Control: max-age=” 也被設定了);
  • 頁面在使用者前進後退的時候還沒有完全載入完或者它有進行中的網路請求,比如 XMLHttpRequest;
  • 頁面進行中IndexedDB操作;
  • 頂層的頁麵包含有frame,並且這些frame由於這裡列的任何一條原因而不能被緩衝;
  • 頁面在一個frame內,並且使用者在這個frame內跳轉到了一個新的網頁,這裡將被緩衝的是新載入的網頁
JS監聽pageshow事件阻止頁面進入bfcache
12345
window.addEventListener(‘pageshow‘, function( e ){if (e.persisted) {window.location.reload()}})

 

Safari、UC、qq瀏覽器測試通過。但是UC、qq瀏覽器會先閃過bfcache中的頁面,因為pageshow是在load事件觸發之後才觸發的。browser依然會保留紅色,我認為是因為browser回到上頁時不觸發任何事件。

JS監聽pagehide事件阻止頁面進入bfcache
123456789
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回到上頁時不觸發任何事件。

給響應添加Cache-Control的header

程式碼範例如下:
在jsp模板的header部分加入如下的禁用緩衝設定:

1234567
<head><%response.setHeader("Cache-Control","no-cache,no-store,must-revalidate");response.setHeader("Expires", "0");response.setHeader("Pragma","no-cache");%></head>

 

安卓webview cache的解決方案

該方案的前提是瀏覽器在向server請求頁面時,每次都用jsp重建html。需要頁面本身有禁用緩衝的配置。

12345678910111213141516171819
<!-- 安卓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_VERsessionStorage.PAGEVERSION = REMOTE_VER;}}</script><!-- 安卓webview 後退強制重新整理解決方案 END -->

 

總結
  1. PC瀏覽器,設定禁用頁面緩衝header即可實現後退重新整理

  2. 支援bfcache/page cache的移動端瀏覽器,JS監聽pageshow/pagehide,在檢測到後退時強制重新整理

  3. 在前2個方案都不work的情況下,可以在HTML中寫入服務端頁面產生版本號碼,與本機存放區中的版本號碼對比判斷是否發生了後退並使用緩衝中的頁面

解決手機上頁面返回但是頁面js沒有重新整理的痛點

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.