這樣講 webStorage,面試官會對你另眼相看

圖片:Unsplash
做者:Erda Estremera

localStorage 只在相同的域下共享同一空間。協議和端口都有影響,注意:javascript

  • http://a.comhttps://a.com不共享
  • http://a.com:80http://a.com:8080 不共享
  • http://a.comhttp://a.com:80 共享

✔ 經常使用 API

設置 localStorage

Chrome 面板查看

  • localstorage.setItem(key, value) 存數據,key value 都會被轉換成字符串,爲了防止意料以外的狀況,最好先將其轉化爲字符串了再存儲;
  • localstorage.getItem(key) 獲取數據,key 都會被轉換成字符串;
  • localstorage.clear() 清除當前域下 localStorage 存儲的數據;
  • localstorage.length 獲取當前域下存儲的項目條數;
  • localstorage.key(n:number) 獲取顯示面板中第 n 條的 key,感受比較雞肋;

✔ 瀏覽器對 localStorage 容量限制

經測試,Chrome、FireFox、Edge 都是 5M(IE 忽略)。html

下面是容量探測代碼,能夠精確到 1K。前端

const add10KStr = new Array(1024).fill('0000000000').join('') // 10240 Byte => 10K
const add1KStr = new Array(1024).fill('1').join('') // 1024 Byte => 1K
const storageKey = 'QuotaTest'

function localStorageQuota() {
  localStorage.clear()
  function setText(str) {
    console.log(str)
  }
  let total = ''
  let interval = null
  interval = setInterval(() => {
    try {
      setText(`數據插入中 => ${total.length / 1024}K`)
      localStorage.removeItem(storageKey)
      localStorage.setItem(storageKey, total + add1KStr)
      total += add10KStr
    } catch (e) {
      clearInterval(interval)
      if (e && e.code === 22) {
        setText('超過容量(10K增長)')
        setText(`當前存儲了${total.length / 1024}K`)
        interval = setInterval(() => {
          try {
            setText(`數據插入中 => ${total.length / 1024}K`)

            localStorage.removeItem(storageKey)
            localStorage.setItem(storageKey, total + add1KStr)
            total += add1KStr
          } catch (ee) {
            clearInterval(interval)
            if (ee && ee.code === 22) {
              setText('超過容量(1K增長)')
              setText(`當前存儲了${total.length / 1024}K`)
            }
          }
        }, 0)
      }
    }
  }, 0)
}
複製代碼

以 Chrome 爲 例,插入不了的時候會拋出異常,e.code 是 22。java

localStorage error

✔ Storage Event

Storage 事件能夠用來在同域下的頁面之間實現廣播機制,該事件是在 window 上觸發的。該事件不在致使數據變化的當前頁面(tab)觸發(若是瀏覽器同時打開一個域名下面的多個頁面,當其中的一個頁面改變 localStorage 的數據時,其餘全部頁面的 storage 事件會被觸發,而原始頁面並不觸發 storage 事件);nginx

event 包含的關鍵信息:git

  • event.key 發生變動的 key
  • event.oldValue 變動以前的值;
  • event.newValue 變動以後的值;

觸發的條件有兩個:github

  1. 不在當前的 tab 觸發,相同的 url 在兩個不一樣的 tab 也是會觸發的;
  2. localstorage.setItem(key, value) 只有當後一次設置的 value 不一樣的時候纔會觸發該事件,相同的話也沒有必要觸發了;

例如在 https://a.com/a.html 有以下代碼:sql

localStorage.setItem('name', 'lx')
window.addEventListener('storage', e => {
  console.log('e', e)
})
複製代碼

這個時候,在 https://a.com/b.html 進行了下面的操做:json

localStorage.setItem('name', 'lxfriday')
複製代碼

則 a 頁面會打印出下面的內容:瀏覽器

storage event

✔ localStorage 的其餘用途

ref

  1. 緩存靜態文件;
  2. 做爲前端 DB 的存儲介質;

✔ sessionStorage

它與 localStorage 類似,不一樣之處在於 localStorage 裏面存儲的數據沒有過時時間設置,而存儲在 sessionStorage 裏面的數據在頁面會話結束時會被清除(關閉當前頁面的時候會清除)

頁面會話在瀏覽器打開期間一直保持,而且 從新加載(刷新) 或恢復頁面仍會保持原來的頁面會話。在新標籤或窗口打開一個頁面時會複製頂級瀏覽會話的上下文做爲新會話的上下文,這句很差理解,意思是點擊當前頁面的 <a target="_black"></a> 標籤時,在新頁面中的 sessionStorage 的值是複製的當前頁面的,注意並非共用的。

✔ sessionStorage 應用

  1. 存儲用戶輸入的內容,當頁面刷新的時候能夠馬上顯示出刷新前的內容;
  2. 對使用 browser historay 部署的單頁應用,能夠在前端使用 sessionStorage 實現路由匹配(不會報 404),不須要使用 nginx 作一次轉發;

實現自動匹配路由的過程是這樣的:當訪問 a.com/page1 頁面的時候,因爲服務器並無這個頁面,服務器會返回 404.html(瀏覽器當前的路由仍然是 a.com/page1),瀏覽器執行 404.html 時會先設置 sessionStorage.redirect 爲當前的 url,而後 <meta> 會馬上讓頁面跳轉到 /,服務器此時會返回 index.html,瀏覽器執行 <script> 中的代碼獲取到 sessionStorage.redirect,而後執行 history.replaceState 替換當前的 url,這樣就達到了想要的跳轉效果(histpry.replaceState 只會更改瀏覽器地址欄,不會讓瀏覽器主動去服務器獲取對應的頁面)。

設置一個 404.htmlhead 中包含下面內容

<head>
    ...
    <script> sessionStorage.redirect = location.href; </script>
    <meta http-equiv="refresh" content="0;URL='/'"></meta>
</head>
複製代碼

在單頁應用的模板 index.html 中,填下面的代碼:

<body>
  <div id="root"></div>
  <script> // 這段代碼要放在其餘js的前面 ;(function() { var redirect = sessionStorage.redirect delete sessionStorage.redirect if (redirect && redirect != location.href) { history.replaceState(null, null, redirect) } })() </script>
</body>
複製代碼

演示

sessionStorage 實現頁面跳轉


關注公衆號,回覆 加羣 ,添加號主微信,將會拉你進交流羣,有任何問題都會回覆,歡迎加入。

感謝閱讀,歡迎關注個人公衆號 雲影 sky,帶你解讀前端技術,掌握最本質的技能。

公衆號
相關文章
相關標籤/搜索