一篇文章圖文並茂地帶你輕鬆學會 HTML5 storage

html5 storage api

localStoragesessionStoragehtml5 新增的用來存儲數據的對象,他們讓咱們能夠以鍵值對的形式存儲信息。html

爲何要有 storage ?

咱們已經有了 session 能夠幫助咱們存儲信息,爲什麼還須要 storage 呢?前端

  1. 各個瀏覽器的 cookie 長度大概只能在 4kb 左右,而 storage 大概能達到 5M,這意味着能夠存儲更多的信息
  2. cookie 能夠被後端更改,在每次進行網絡請求的時候都會被髮送給服務器,而 storage 不會,這意味着這個存儲是徹底受控於前端(JavaScript)的。

storage 類型

storage 一共有兩種html5

  1. localStoragechrome

    這個存儲對象的存儲和 origin 有關,即只要是同域名同協議同端口,存儲是共享的。儘管關機了,或是關掉瀏覽器了,只要打開同源網站,存儲的數據會依然存在,數據不會過時消失。後端

  2. sessionStorageapi

    這個存儲對象的存儲是暫時的,只保持在當前會話中,簡單來講就是和瀏覽器的一個 tab 有關,只要 tab 關掉了再打開數據就沒了,可是在當前界面刷新的話,數據就還在(這個時候認爲是一個 tab)。數組

兩個 storageapi 很類似,下面以 localStorage 爲例瀏覽器

localStorage 演示

基礎 api

localStorage.setItem("name", "huro"); // 設置鍵值對

能夠在 chrome 瀏覽器的控制檯進行觀察,這裏已經設置上去了。下面也能夠作相應的測試。服務器

localStorage.getItem("name"); // huro
localStorage.removeItem("name"); // 刪除某個鍵
localStorage.clear(); // 刪除全部鍵值對
localStorage.key(0); // 得到索引爲 0 的key
localStorage.length; // 得到 `localStroage` 的鍵的個數

以上是 storageapicookie

惟一須要注意的是 key(index) 這個 apikey 被設置的前後是沒有關係的。

類對象操做

也能夠用類對象的方法操做

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

  1. 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

  1. 簡單 for 循環
for(let i = 0; i < localStorage.length; i+= 1) {
  let key = localStorage.key(i);
  console.log(key);
}

這個時候能正確的只打印出鍵 name

  1. 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 事件返回一個對象,裏面包含幾個參數

  1. key 改變的鍵
  2. oldValue => 舊值 || null
  3. newValue => 新值 || null
  4. url 觸發這個事件的 url 地址
  5. 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.htmltest2.html 都設置了 storage 監聽事件,且同源。

test1.htmlstorageapi 事件會觸發 test2.html 的,可是不能觸發自己的 storage 監聽事件。

另外這裏的 api 事件也有限制,通過筆者測試,彷佛只有

  1. setItem
  2. getItem
  3. removeItem

有效果,而 clear 事件是沒有效果的。
上面全程用 localStorage 演示,

sessionStorage 也是相似的,讀者有興趣能夠自行碼一下代碼。

總結

storage 是很好的一個 html5 特性,讓咱們方便快捷的存儲數據,美中不足的是隻能存儲字符型數據,不過也很容易解決這個問題。同時利用監聽事件,也能夠實現不一樣窗口之間的廣播機制。是很是實用的一個特性。

相關文章
相關標籤/搜索