在開發一個移動應用的過程中,遇到問題:在訂單確認頁,用戶點擊 收貨地址鏈接,跳轉到地址選擇頁面,咋選一個地址,跳轉回訂單確認頁,發現收貨地址沒有改變,還是最開始的地址。
用Android手機發現地址有更新,而Iphone手機地址沒有更新。
通過查詢資料,發現是如下原因造成:
“此問題是由於某些瀏覽器在back的時候是直接使用的之前的視圖,頁面沒有進行重新加載而導致的,在網上找了些資料, 發現這是H5的一些新特性Back-Forward Cache(簡稱bfcache) ,普通瀏覽器在back時,如果不是指定Cache-Control、Expires等方法強制停用Cache時,那么一般情況下瀏覽器大多數都會直接讀取本地的緩存, 減少請求和網絡傳輸的成本, 增加瀏覽的順從度, 但Cache僅限於靜態文件, 瀏覽器還是得重新加載html, 重新執行腳本,渲染DOM, 而bfcache則不同, 是直接讀取緩存里面的html,節省了重新請求頁面的時間, 既然是讀取緩存的html頁面, 那么執行頁面的onload事件進行初始化, 會影響原本因用戶操作而改變的狀態, 所以瀏覽器在back時是不會觸發onload事件.”
這個時候就會產生上面的問題, 有些業務在返回時是需要重新加載的, 於是H5新增了兩個事件onpageshow和onpagehide, 分別是進入網頁和離開的時候觸發, 即使是用瀏覽器的前進/后退也會觸發這兩個事件.
“Firefox和Safari會bfcache, back時不會觸發load, ready事件, 只會觸發onpageshow, 而chrome雖然支持onpageshow, 但是back時一樣都會觸發load,ready事件, opera最操蛋, back時會bfcache,但是不觸發onpageshow事件.”
==========================================================================================================================================
解決方案:
嘗試過在頁面加上:
<meta http-equiv='cache-control' content='no-cache'>
<meta http-equiv='expires' content='0'>
<meta http-equiv='pragma' content='no-cache'> 但發現不起作用。
也用過別人的解決方法: $(window).unload(function () { }); 但發現不起作用。
最終使用:
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};
成功解決問題。
可以檢查pageshow
事件的persisted屬性,當頁面初始化加載的時候,persisted被設置為false,當頁面從緩存中加載的時候,persisted被設置為true。因此,上面代碼的意思就是:
如果頁面是從緩存中加載的,那么頁面重新加載。
參考文獻:
http://www.cnblogs.com/AeroJin/p/4783408.html
http://stackoverflow.com/questions/10106457/pageshow-is-not-received-when-pressing-back-button-on-safari-on-ipad
https://github.com/christophery/pushy/issues/51