localStorage
和 sessionStorage
是 html5
新增的用來存儲數據的對象,他們讓咱們能夠以鍵值對的形式存儲信息。html
storage
?咱們已經有了 session
能夠幫助咱們存儲信息,爲什麼還須要 storage
呢?前端
cookie
長度大概只能在 4kb
左右,而 storage
大概能達到 5M
,這意味着能夠存儲更多的信息cookie
能夠被後端更改,在每次進行網絡請求的時候都會被髮送給服務器,而 storage
不會,這意味着這個存儲是徹底受控於前端(JavaScript)的。storage
一共有兩種html5
localStorage
chrome
這個存儲對象的存儲和 origin
有關,即只要是同域名同協議同端口,存儲是共享的。儘管關機了,或是關掉瀏覽器了,只要打開同源網站,存儲的數據會依然存在,數據不會過時消失。後端
sessionStorage
api
這個存儲對象的存儲是暫時的,只保持在當前會話中,簡單來講就是和瀏覽器的一個 tab
有關,只要 tab
關掉了再打開數據就沒了,可是在當前界面刷新的話,數據就還在(這個時候認爲是一個 tab
)。數組
兩個 storage
的 api
很類似,下面以 localStorage
爲例瀏覽器
api
localStorage.setItem("name", "huro"); // 設置鍵值對
能夠在 chrome
瀏覽器的控制檯進行觀察,這裏已經設置上去了。下面也能夠作相應的測試。服務器
localStorage.getItem("name"); // huro localStorage.removeItem("name"); // 刪除某個鍵 localStorage.clear(); // 刪除全部鍵值對 localStorage.key(0); // 得到索引爲 0 的key localStorage.length; // 得到 `localStroage` 的鍵的個數
以上是 storage
的 api
cookie
惟一須要注意的是 key(index)
這個 api
和 key
被設置的前後是沒有關係的。
也能夠用類對象的方法操做
localStorage.name = "huro"; console.log(localStorage.name); // huro delete localStorage.name; // 刪除鍵
可是上面的作法不推薦,若是用的是某些特殊的 key
例如 length
就會報錯,由於原先 localStorage.length
表示得到鍵值對長度,理應是不能修改的。
localStorage["length"] = 4; // 修改無效
所以不推薦用這個作法修改 storage
因爲 storage
並無 Symbol.iterator
屬性,這意味着 storage
不能用 for of
循環遍歷。如下有三種遍歷方式。
假設咱們只有一個鍵值對 name: huro
for in
循環for (let key in localStorage) { console.log(key); }
上述的寫法是錯誤的,由於 for in
循環會遍歷原型鏈上的屬性和方法,所以須要稍做改善。
for (let key in localStorage) { if (!localStorage.hasOwnProperty(key)) { continue; } console.log(key); }
這個時候就能正確的只打印出鍵 name
for
循環for(let i = 0; i < localStorage.length; i+= 1) { let key = localStorage.key(i); console.log(key); }
這個時候能正確的只打印出鍵 name
Object.keys()
這個方法會得到某個對象自身的 key
,而不會管原型鏈上的
const keys = Object.keys(localStorage); for(let key of keys) { alert(key); }
並且得到的 key
是數組,具備 iterator
所以能夠用 for of
遍歷
這個時候能正確的只打印出鍵 name
string
storage
被設計出來比較不足的地方是,鍵和值都只能是 string
類型的,若是不是的話,會自動轉換成 string
。
因爲是隱式轉換,初學者每每不知道,這意味着可能帶來一些 bug
localStorage.user = { name: "huro" }; console.log(localStorage.user); // [object Object]
上述代碼在存儲 user
的時候,被自動調用 toString
方法,轉化爲了 [object Object]
storage
事件storage
事件返回一個對象,裏面包含幾個參數
key
改變的鍵oldValue
=> 舊值 || null
newValue
=> 新值 || null
url
觸發這個事件的 url
地址storageArea
要麼是 localStorage
要麼是 sessionStorage
取決與是更改哪一個storage
的// 1.html window.addEventListener("storage", (state) => { console.log(state.key, state.value, state.url); // name huro ./2.html(實際 url 是絕對路徑) }) // 2.html localStorage.setItem("name", "huro");
還記得咱們以前說過, localStorage
只要是同源均可以分享嗎,這意味若是咱們打開了兩個窗口,只要他們是同源的,咱們能夠用上述的監聽事件,監聽另外一個端口修改 storage
,也就是能夠實現不一樣的窗口之間的數據共享。
注意: 經測試,chrome
edge
等現代瀏覽器不會觸發自身文件或同文件的 storage
事件,即必須是兩個不一樣的 html
纔會互相觸發。
例如 test1.html
和 test2.html
都設置了 storage
監聽事件,且同源。
則 test1.html
的 storage
的 api
事件會觸發 test2.html
的,可是不能觸發自己的 storage
監聽事件。
另外這裏的 api
事件也有限制,通過筆者測試,彷佛只有
setItem
getItem
removeItem
有效果,而 clear
事件是沒有效果的。
上面全程用 localStorage
演示,
sessionStorage
也是相似的,讀者有興趣能夠自行碼一下代碼。
storage
是很好的一個 html5
特性,讓咱們方便快捷的存儲數據,美中不足的是隻能存儲字符型數據,不過也很容易解決這個問題。同時利用監聽事件,也能夠實現不一樣窗口之間的廣播機制。是很是實用的一個特性。