認識瀏覽器的神秘儲存空間 - localStorage

By 哲昱・7月 5 2021・技術文章
認識瀏覽器的神秘儲存空間 - localStorage

前言

在瀏覽網站的時候,可以根據我們的喜好更換版面,即使重新整理或關閉瀏覽器後,再度開啟該網站時,設定居然都還存在!或者是購物網站,將物品加入購物車,但沒有結帳就關掉瀏覽器,過了很久之後,再次去買東西,購物車裡的物品也都還在,究竟是為什麼呢?其實透過後端做存取就可以解決這個問題了,但瀏覽器也有個神秘的儲存空間可以提供我們做使用,就是 localStorage。

這篇文章,將帶大家來了解什麼是 localStorage ? 如何使用 localStorage?

localStorage 基本介紹

隨著瀏覽器不斷的進步,功能也越來越強大。在 HTML5 出來之前,我們只能將最多 4K 的資料儲存在 cookie 裡面。現在 HTML 5 中,新加入了 Local Storage 作為本地儲存來使用,一般瀏覽器容量為 5M(不同瀏覽器支援的容量會有所不同)。

LocalStorage 優缺點

優點:

  1. 增加本地儲存空間。
  2. 儲存資料方式,為 keyvalue

P.S. keyvalue 資料儲存型態為 String

缺點:

  1. value 儲存型態只接受 String
  2. 無痕或隱私模式下無法讀取。
  3. 資料量太多,存取時,容易照成畫面卡頓。
  4. 有些比較較舊的瀏覽器版本(IE 8 以下)沒有支援。

localStorage 與 sessionStorage 的差異

在使用方法上大致相同,只有以下的差異:

  1. localStorage 的資料是永久存在,唯有清除它才會消失。
  2. sessionStorage 的資料則是當網頁關閉時,就會清除。

localStorage 的使用方法

  1. localStorage.setItem('key', 'value'):透過 setItem() 方法中將物件屬性的 keyvalue 當成參數傳入,我們就可以在 storage 物件中加入屬性或修改原本的屬性內容。

  2. localStorage.getItem('key'):透過 getItem() 方法將屬性的 key 當成參數傳入,我們就可以得到 storage 物件對應的 value

  3. localStorage.key():透過 key() 方法中輸入屬性的順序位置,我們可以取得 storage 物件中該位置的屬性 key,而位置順序和陣列表示方法一樣,由 0 開始。

  4. localStorage.removeItem():透過 removeItem() 方法,我們可以把指定的屬性從 storage 物件中移除。

  5. localStorage.clear():透過 clear() 方法,我們可以直接把 storage 中的所有屬性移除。

localStorage 簡單練習

練習畫面-1

我們來運用 localStorage 來實作簡易一個會員登入系統。 (溫馨小提醒:這邊單純範例練習,實務上有關於使用者的基本資料或者密碼,請勿將這些資訊存放在 localStorage 上。)

步驟一:創建帳號

步驟一:創建帳號

當我們按下 SIGN UP button 後,就會跳出 alert 提醒創建成功。

接下來就會在 localStorage (開發者工具 => Application => Storage => Local Storage) 裡面出現剛剛輸入的資料。

而這邊我們是將使用者的帳號密碼組合成 localStorage 的 key,把 Name 成為 value,使用 setItem() 方法進行儲存。

signUpBtn.addEventListener('click', () => {
    const signUpName = document.querySelector('#signUpName')
    const signUpEmail = document.querySelector('#signUpEmail')
    const signUpPassword = document.querySelector('#signUpPassword')
    const storageKey = signUpEmail.value + signUpPassword.value //將使用者的帳號密碼組合成 Key
    const checkUser = Boolean(localStorage.getItem(storageKey))

    function successAction() {
      if(checkUser) {
        return alert('The email has already created it, please re-enter')
      }

      // 使用 setItem() 方法來儲存資料
      localStorage.setItem(storageKey, signUpName.value)
      signUpName.value = ''
      signUpEmail.value = ''
      signUpPassword.value = ''
      alert('Created successfully, please go to sign in page')
    }

    if(signUpEmail.value === '' || signUpPassword.value === ''){
      alert('The input box cannot be empty')
    } else {
      successAction()
    }
  })

步驟二:登入

步驟二:登入

我們一開始可以看到 Local Storage 裡面有屬性 [email protected],而相對應的 value 為 CY ,當我們輸入完帳號密碼後組成了 key ,然後使用 Local Storage 的 getItem() 方法,將相對應的 value 取出,在組合字串最後渲染出來。

這邊偷偷埋個下一步要解決的關鍵要素,就是當我們成功登入時,在 localStorage 多了一個 MemoryAccount 的屬性,有發現嗎 ? 而究竟為什麼呢 ? 將在下一步揭曉。

loginBtn.addEventListener('click', () => {
  const loginEmail = document.querySelector('#loginEmail')
  const loginPassword = document.querySelector('#loginPassword')
  const sayHiElement = document.querySelector('.sayHi')
  const storageKey = loginEmail.value + loginPassword.value // 將帳號密碼組成 Key。
  const userName = localStorage.getItem(storageKey) // 這邊將 Name(CY) 從 localStorage 裡面取出來
  const checkUser = Boolean(userName)

  function loginAction() {
    if(!checkUser) { 
      return alert('Please create an account first')
    } 

    const confirmMemory = confirm('Do you want to save this password?')
    loginEmail.value = ''
    loginPassword.value = ''
    alert('sign in suceesfully')
    // 這邊將從 localStorage 取出的文字和 Hi~ 組合成一個字串。
    sayHiElement.textContent = `Hi~ ${userName}` 
    if(confirmMemory){
      //暴雷一下,這裡再儲存一次是為了重新整理或關掉頁面,可以維持登入狀態。
      localStorage.setItem('MemoryAccount', `Hi~ ${userName}`) 
    }
  } 

  if(!loginEmail.value || !loginPassword.value){
    alert('The input box cannot be empty')
  } else {
    loginAction()
  }
})

步驟三:重新整理

步驟三:重新整理

我們預期重新整理後,『 Hi~ CY 』還是會在,為什麼呢 ? 那是因為我們在上一個步驟登入時,第一個 alert 問我們的是 『 Do you want to save this password ? 』 選擇 『 是 』 後,程式根據我們的回答進行儲存資料。

接下來當我們重新整理時,我們會去 localStorage 裡面找 MemoryAccount 屬性,並拿出我們儲存的 value 渲染在畫面上。

function firstRnder() {
  const sayHiElement = document.querySelector('.sayHi')
  const storageMemory = localStorage.getItem('MemoryAccount') //這邊取出上次使用者的資訊
  let status = localStorage.getItem('status')
  !status && localStorage.setItem('status', 'login')
  if(storageMemory){
    //判斷是否有使用者的資訊,再去執行第 8 行渲染
    sayHiElement.textContent = storageMemory
  }
  changePage()
}

步驟四:登出

步驟四:登出

最後我們要來實現登出,這是所有步驟中最簡單的,只要使用 clear() 方法將 localStorage 裡面的資料清除即可。

logOutLink.addEventListener('click', () => {
  const sayHiElement = document.querySelector('.sayHi')
  localStorage.clear() //使用 clear 方法,清除所有資料。
  sayHiElement.textContent = 'Hello, Friend !'
})

Codepen 連結 :https://codepen.io/ice12031110/full/PomoBOR

結語

當我們製作網頁時,如果此頁資料是必須帶往下一頁或者是離線狀態使用,localStorage 這時候就可以派上用場。

雖然 localStorage 非常方便,但在使用時,須注意儲存的資料是否為重要資料,因為 localStorage 只要打開開發者工具就能看到,毫無安全性可言,任何人都可以對其進行修改。

而這邊使用登入的例子,是為了帶大家使用 localStorage 的方法,也藉此說明 localStorage 須注意的事項。

這次實作範例有放在 Codepen 上面,對此篇文章有任何問題歡迎 來信 與我討論。

最後,希望透過這篇文章,能讓大家對 localStorage 不再陌生。

謝謝你的閱讀!


👩‍🏫 課務小幫手:

✨ 想掌握 JavaScript 觀念和原理嗎?

我們有開設 📒 JavaScript / jQuery 前端開發入門實戰 課程唷 ❤️️