localStorage的寫入和讀取,不能跨子域,不然在一些移動端瀏覽器上,會出現讀取不到的狀況。javascript
最近開發一個移動端的播放記錄功能,在pc端和android版的chrome測試很順利經過了,但後來進行多平臺測試的時候,悲劇發生了。。html
android版本UC、iphone及ipad mini版的safari,localStorage跨頁面讀取不到數據,必需要重啓瀏覽器後纔可以正常的讀取到數據。java
首先懷疑的多是localStorage的訪問方式的問題,寫入的方式是屬性設置localStorage.history而讀取是api的方式localStorage.getItem,demo後確認localStorage的三種訪問方式都是沒有問題的。android
思惟短路了,開始思考如何規避這個跨頁面沒法讀取的問題,首先想到的是嘗試下sessionStorage,瀏覽器運行期間將數據保存在「session」中,後來發現有着一樣的問題。chrome
繼續思考可以跨頁面保存「大數據」的方式,「靈光」閃現,window.name應該是能夠跨頁面保存的,試了下各類設備確認這種方案確實可行,可是風險是任何頁面都有可能重寫掉這個name,甚至會有安全問題。api
用極簡的demo測試,發現這些有問題的瀏覽器對localStorage的支持是沒問題的。在幾乎要放棄的時候,同事跑過來講,將某個文件提早到head裏,能夠正常的讀取數據,這是才意識到播放器的前置代碼裏沒有顯示的設置document.domain,致使讀取和設置localStorage在不一樣的domain下面發生的。瀏覽器
在寫入localStorage的頁面方法以前沒有顯示的設置document.domain,默認的值爲 labs.wxnet.me,可是在讀取的頁面,讀取數據以前顯示的設置了document.domain爲根域wxnet.me安全
寫入數據的頁面 http://labs.wxnet.me/labs/writelocalstorage.htmlsession
//document.domain默認值爲子域 labs.wxnet.me localStorage['k'] = '{"a":"1"}'; document.domain = "wxnet.me";
讀取數據的頁面 http://labs.wxnet.me/labs/readlocalstorage.htmldom
document.domain = "wxnet.me"; alert(localStorage['k']);
讀取和設置localStorage的頁面必需要統一document.domain,要麼所有不顯示設置或統一設置爲根域。
設置頁面:
document.domain = "wxnet.me"; localStorage['k'] = '{"a":"1"}';
讀取頁面:
document.domain = "wxnet.me"; alert(localStorage['k']);
不一樣的移動版瀏覽器在處理子域方式不一樣,iphone、ipad mini子域下寫入,主域下是沒法讀取的,重啓瀏覽器後忽略掉這個安全策略,能夠讀到數據。可是ipad、pc版的瀏覽器沒有發現這個問題。