HTML5 localStorage與document.domain設置問題

localStorage的寫入和讀取,不能跨子域,不然在一些移動端瀏覽器上,會出現讀取不到的狀況。javascript

最近開發一個移動端的播放記錄功能,在pc端和android版的chrome測試很順利經過了,但後來進行多平臺測試的時候,悲劇發生了。。html

掉進localStorage的坑裏

android版本UC、iphone及ipad mini版的safari,localStorage跨頁面讀取不到數據,必需要重啓瀏覽器後纔可以正常的讀取到數據。java

爬出localStorage的坑

首先懷疑的多是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安全

將問題環境抽象爲demo

寫入數據的頁面 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版的瀏覽器沒有發現這個問題。

相關文章
相關標籤/搜索