
打個比方,localStorage 有點像瀏覽器中的長期資料庫或是檔案櫃,只要你不主動清除,它就會一直保存資料;而 sessionStorage 則比較像臨時的便利貼,當你關閉該瀏覽器分頁或視窗時,便利貼上的內容就被丟掉了。本文將深入介紹 localStorage 和 sessionStorage 的基本原理,詳細比較它們在儲存容量、資料壽命、作用範圍等技術層面的差異,並透過幾個實際案例來說明何時該用哪一種。最後,我們還準備了一個 FAQ 單元來解答常見的疑問,例如資料能否跨網頁共享、應該在何種情況下使用 localStorage、以及使用上是否安全等問題。讓我們開始探索這兩種瀏覽器儲存方式的奧妙吧!
localStorage 與 sessionStorage 是什麼?
首先,我們來認識一下這兩位主角。localStorage 和 sessionStorage 都是 HTML5 引入的 瀏覽器端儲存機制,屬於 Web Storage API 的一部分。它們允許我們透過 JavaScript 在使用者的瀏覽器中保存資料。與傳統的 Cookie 相比,Web Storage 提供了更大的容量,且存取時不會自動夾帶在每一次的 HTTP 請求中(這意味著我們可以儲存較多資料而不增加每次網路請求的負擔)。更棒的是,它們的使用方式非常直觀:
// 將資料存入
localStorage.setItem('key', 'value');
sessionStorage.setItem('key', 'value');
// 從儲存中讀取資料
let localValue = localStorage.getItem('key');
let sessionValue = sessionStorage.getItem('key');
在以上程式碼中,我們使用 setItem 方法保存一筆資料,getItem 方法讀取資料。兩者的 API 幾乎一模一樣,都可以用來建立、讀取、更新和刪除資料(分別對應 setItem、getItem、setItem 覆蓋同鍵值、以及 removeItem 或 clear)。看起來很類似對吧?事實上,localStorage 和 sessionStorage 在操作上確實如出一轍,差別不在用法,而在它們保存資料的範圍和時間上。
還有一點要注意:無論是 localStorage 還是 sessionStorage,同源政策(same origin policy)都適用。也就是說,只有同一個網域(以及相同協議和埠)下的網頁可以存取彼此的 Web Storage 資料。其他網域的網頁無法讀取你的儲存內容,確保了不同網站之間資料的隔離。了解了這些共同點後,我們來看看 localStorage 與 sessionStorage 在關鍵特性上的差異。
差異比較:儲存容量、資料壽命與作用範圍
儘管 localStorage 和 sessionStorage 的使用方式相同,它們在「能存多少、可以存多久,以及在哪些地方存取」這三方面存在明顯差異。我們逐一比較如下:
儲存容量
兩者的容量限制通常是相同等級的,現代瀏覽器為每個網域提供大約 5MB 左右的 Web Storage 空間(不同瀏覽器略有差異,約在 5MB~10MB)。相較於 Cookie 約 4KB 的可用容量,localStorage 和 sessionStorage 可謂容量充裕,能夠儲存更多、更複雜的資料(例如清單或物件的 JSON 字串)。在容量方面,localStorage 和 sessionStorage 並沒有彼此優劣之分——它們都讓前端開發者不再受到幾千字節的侷限,可以放心保存一些中等規模的資料而不必頻繁與伺服器交互。
資料壽命
這是 localStorage 和 sessionStorage 最大的差別所在。localStorage 保存的資料是持久的:一旦存入資料後,除非透過程式碼或使用者手動清除,資料將一直保留在瀏覽器中。即使你關閉瀏覽器、重開機,過了一週再訪問同一網站,之前存在 localStorage 裡的資料依然存在。因此 localStorage 非常適合需要長期保存的資訊,例如使用者偏好設定、主題顏色、長期的登入憑證等。
sessionStorage 則相反,它的資料生命週期極短:僅在當前瀏覽器會話(session)中有效。一旦你關閉了該瀏覽器的分頁或視窗(結束了那個 session),存放在 sessionStorage 的所有資料就會被瀏覽器自動清除。不僅如此,如果你在同一個分頁中重新整理或導覽至同一網站的其他頁面,sessionStorage 的資料會跟隨著該分頁持續存在(因為仍在同一會話中),但不會在你完全關閉分頁後保存下來。簡而言之:localStorage 是永久保存(除非主動清除),而 sessionStorage 是暫時保存到分頁關閉為止。
作用範圍
兩者在作用範圍(Scope)上的差異決定了資料能在哪些情況下被存取。localStorage 的作用範圍是整個網域;只要是在同源的條件下(相同的網域/主機名稱),不同的瀏覽器分頁甚至不同的瀏覽器視窗,都共享同一套 localStorage 資料。例如,你在 example.com 的首頁將某資料寫入 localStorage,那麼用同一瀏覽器再開另一個標籤頁造訪 example.com/profile 時,也可以讀取到同樣的資料。換句話說,localStorage 是同網域全局共享的。
相比之下,sessionStorage 的作用範圍被限制在單一瀏覽器分頁或視窗。每開啟一個新的分頁視窗,即使網址相同,都會得到各自獨立的 sessionStorage 空間,彼此無法存取對方的資料。舉例來說,你在某網站的分頁 A 中將資料寫入 sessionStorage,再手動開啟另一個分頁 B 訪問同一網站時,B 分頁的 sessionStorage 預設是空的,並不會看到 A 分頁的資料。因此 sessionStorage 適合儲存只與特定瀏覽過程相關的資訊。而 localStorage 則方便在同網站的不同頁面甚至不同訪問時期共用資料。
小延伸:特別一提,若你是透過點擊連結的方式從分頁 A 打開了一個新的分頁 B(而非手動另開分頁並輸入網址),按照規範瀏覽器可能會將 A 的 sessionStorage 複製一份給 B,讓 B 能夠在載入時取得 A 當前的 sessionStorage 資料。但這並不代表兩者共享實時更新的儲存空間——B 之後的變動不會影響 A。這種行為算是瀏覽器對新開分頁的一種便利性處理,但一般來說,我們仍將 sessionStorage 視作不在不同分頁間共享。
概括而言,localStorage 注重跨頁面、長期間的資料保存,而 sessionStorage 則強調當下會話、分頁的獨立性。了解了這些差異之後,接下來讓我們看看在實際開發中,應該如何利用各自的特性,並搭配範例程式碼來說明在不同情境下該選擇哪一種儲存方式。
實際應用案例
紙上談兵或許還不夠具體。我們接下來透過幾個常見的應用場景,來體驗 localStorage 和 sessionStorage 各自的用武之地。以下每個案例都會包含說明和對應的純 JavaScript 範例程式碼,示範如何實作。
案例一:登入狀態儲存
情境說明:在使用者登入網站後,我們通常希望即使使用者稍後關閉瀏覽器,下一次回來時仍然是保持登入狀態,而不需要再次輸入帳密。為了實現「記住我」的功能,我們可以利用 localStorage 將登入資訊保存下來。由於 localStorage 資料會永久保存(除非被清除),它非常適合存放像登入憑證或登入狀態這類需要長期保存的資料。相對地,如果我們希望使用者一關閉頁面就強制重新登入(例如網銀等高安全性情境),就不會使用 localStorage,而可能選擇會話性較強的 sessionStorage 或其他方案。以下是使用 localStorage 實現簡單登入狀態保存的範例:
// 使用者成功登入後,將重要資訊存入 localStorage
localStorage.setItem('authToken', 'ABC123456'); // 保存認證令牌(範例值)
localStorage.setItem('username', '小明'); // 保存使用者名稱
// 在後續頁面載入時(例如重新整理或造訪網站的其他頁面),檢查 localStorage 中是否有登入資訊
const token = localStorage.getItem('authToken');
if (token) {
console.log('使用者仍然處於登入狀態,Token:', token);
console.log('歡迎回來,' + localStorage.getItem('username') + '!');
// 在真實應用中,可利用 token 向伺服器驗證或取得用戶資訊
} else {
console.log('使用者未登入或登入資訊已過期。');
}
// 使用者登出時,清除 localStorage 中的相關資料
function logout() {
localStorage.removeItem('authToken');
localStorage.removeItem('username');
console.log('使用者已登出,已清除 localStorage 中的登入資料。');
}
範例說明:上述程式碼模擬了一個簡單的登入狀態維持機制。當使用者登入成功後,我們將一個模擬的認證令牌(authToken)和使用者名稱保存到 localStorage 中。因為 localStorage 資料不會隨瀏覽器關閉而消失,下次使用者再打開這個網站時,我們的腳本可以透過 getItem 取回先前儲存的 token,判斷使用者是否有登入記錄。如果取到了 token,就代表使用者尚未登出過,可以直接讓他保持登入狀態(在真實網站上通常會用這個 token 向後端驗證身份或者自動取得使用者資料)。相反地,如果讀取不到 token,那麼就當作未登入處理。
另外,我們在 logout() 函式中示範了如何清除資料:呼叫 removeItem 刪除特定鍵值,或可使用 localStorage.clear() 清空該網域在 localStorage 中的所有資料。在這個案例中,由於我們是用 localStorage 儲存登入資訊,資料會跨瀏覽器分頁和造訪時段一直存在,符合「記住我」的需求。但如果將上述流程改用 sessionStorage,那麼使用者關閉分頁或瀏覽器後資料就沒了,下次打開網站時便無法自動判斷登入狀態——這對於一些需要自動登入的產品來說顯然不方便。總結:當需要長時間記住使用者狀態時,localStorage 是適合的選擇,但儲存敏感資訊時也要注意安全性(細節在下方 FAQ 討論)。
案例二:購物車資料保存
情境說明:想像你正在逛一個購物網站,選了一些商品加入購物車,但臨時有事關掉了網頁。隔天你再回到這個網站時,發現購物車裡之前選的商品還在,免去了重新挑選的麻煩。這種貼心的體驗可以透過 localStorage 實現。許多電商網站在使用者尚未登入的情況下,會將購物車內容存在 localStorage,以便使用者下次回來時仍能看到之前加入的商品。由於購物車資訊希望能跨多次造訪保留,而且資料量可能不小(包含多個商品項目),localStorage 的永久性和容量優勢非常適合這個情境。下面範例展示如何用 localStorage 保存簡易的購物車清單:
// 將商品加入購物車並存入 localStorage
let cart = JSON.parse(localStorage.getItem('cartItems') || '[]'); // 取得目前購物車陣列(若無則初始化為空陣列)
const newItem = { id: 101, name: "JavaScript 實戰手冊", quantity: 1 }; // 新商品項目
cart.push(newItem); // 加入購物車陣列
localStorage.setItem('cartItems', JSON.stringify(cart)); // 將更新後的陣列存回 localStorage
console.log('已加入購物車,目前共有商品數量:', cart.length);
// 在其他頁面載入或日後回到網站時,讀取 localStorage 中的購物車資料
const savedCart = JSON.parse(localStorage.getItem('cartItems') || '[]');
if (savedCart.length > 0) {
console.log('載入儲存的購物車項目清單:', savedCart);
// TODO: 將 savedCart 的內容顯示在購物車畫面上,例如列出每件商品
} else {
console.log('購物車目前是空的。');
}
範例說明:以上程式碼模擬了一個購物車的資料結構保存。當使用者將商品加入購物車時,我們透過 localStorage.getItem('cartItems') 取得之前存儲的購物車資料(它是一個 JSON 字串),並用 JSON.parse 將其轉回 JavaScript 陣列。如果 cartItems 不存在(第一次操作購物車),我們就以空陣列作為初始值。接著,把新的商品物件加入陣列,再使用 JSON.stringify 將更新後的陣列轉成字串,存回 localStorage。這樣一來,購物車內容就被保存到瀏覽器中了。
當使用者稍後重新打開網站或跳轉到購物車頁面時,我們同樣利用 getItem 取回儲存在 localStorage 裡的購物車資料字串,再解析為陣列,恢復之前保存的狀態,讓使用者可以繼續看到已選購的商品。由於 localStorage 能跨頁面和長時間保存資料,即使使用者關掉瀏覽器過了好幾天,這些資料仍然存在,等待下次載入時使用。這對提升使用者體驗非常有幫助:使用者不需要重複挑選商品,網站也顯得更加智能友好。
需要注意的是,我們在這裡使用了 JSON.stringify 和 JSON.parse,因為 localStorage 只能存儲字串。如果要保存物件或陣列,就必須先序列化成字串格式。類似地,當我們讀取資料時,也要將字串解析回原本的資料類型。如果你存的是數字或布林值,取出時也會是字串型別,需要手動轉型。例如,儲存布林值 true 實際上會存成字串 "true",取出時可能需要比較字串或轉成布林後再用。這些都是使用 Web Storage 時的小細節。
綜上,localStorage 非常適合需要長期保存且可能跨多頁使用的資料,如購物車內容、未登入使用者的偏好設定等。但也要謹慎管理資料量,避免存放過多或不再需要的資訊。在適當的時機(例如確認訂單後或使用者清空購物車時)記得清除或更新 localStorage,以免留存過期的資料。
案例三:單頁應用(SPA)的暫存資料
情境說明:單頁應用程式 (Single Page Application, SPA) 因為通常只在一個頁面中動態更新內容,不會整頁重新載入,所以在使用者操作過程中,我們可能需要暫存一些資料以備不時之需。例如:使用者正在填寫一份多步驟的表單或撰寫一篇文章時,不小心重新整理了頁面——我們希望在重新載入後能夠恢復他剛才已經填入的內容,以免他從頭再來。這種只需要在當前會話中暫存的資料,非常適合使用 sessionStorage。sessionStorage 的資料只要還在同一分頁(會話)就可以存取,即使重新整理或透過 AJAX 局部換頁也不會丟失,但關閉頁面後資料就清空,正符合「暫存暫用」的需求。以下是一個使用 sessionStorage 來暫存 SPA 表單草稿的簡單範例:
// 假設有一個文字輸入欄位讓使用者撰寫留言,我們透過 sessionStorage 來暫存草稿
const messageInput = document.querySelector('#message');
// 頁面載入時,檢查 sessionStorage 裡是否有尚未發送的草稿
const savedDraft = sessionStorage.getItem('draftMessage');
if (savedDraft) {
messageInput.value = savedDraft;
console.log('已從 sessionStorage 載入草稿:', savedDraft);
}
// 在使用者輸入過程中,隨時將最新內容存入 sessionStorage
messageInput.addEventListener('input', () => {
sessionStorage.setItem('draftMessage', messageInput.value);
});
// 當使用者按下「送出」按鈕時,送出留言並清除暫存的草稿
const sendButton = document.querySelector('#sendBtn');
sendButton.addEventListener('click', () => {
const finalMessage = messageInput.value;
// 假設此處執行送出留言的動作,例如透過 AJAX 傳送 finalMessage 至伺服器
sessionStorage.removeItem('draftMessage'); // 清除草稿
console.log('留言已送出,清除暫存草稿。送出的內容:', finalMessage);
});
範例說明:這段程式碼展示了如何在單頁應用中利用 sessionStorage 保障使用者的輸入體驗。我們將一個文字輸入框與 sessionStorage 鏈結:頁面載入時先檢查是否存在已儲存的草稿內容,如果有就預先填入,讓使用者可以銜接上次未完成的輸入繼續編輯。接著,在使用者每次輸入時(透過 input 事件),即時把內容存入 sessionStorage 的 draftMessage 項目中。如此一來,即使使用者不小心刷新了頁面,先前輸入的內容也不會丟失——重新載入後腳本會從 sessionStorage 抓取草稿並填入欄位。
當使用者完成輸入並按下送出,我們在送出的同時呼叫 sessionStorage.removeItem('draftMessage') 將暫存的草稿清除,保持 sessionStorage 的整潔。又因為 sessionStorage 的資料只在當前分頁有效,如果使用者關閉了頁面再重新開啟,這份草稿自然也就不存在了(假設使用者關閉頁面就表示他放棄了草稿,這種情境下資料自動清除反而是預期的行為)。
由此可見,sessionStorage 很適合用來處理短期使用的資料暫存需求,例如 SPA 中的表單草稿、臨時狀態、瀏覽過程中的中間結果等等。我們不必擔心清理問題,因為只要使用者的當前會話結束(分頁關閉),瀏覽器就會幫我們把資料清掉,確保不會在使用者下次造訪時造成干擾。這提供了使用者在「當下」的良好體驗,又不會影響「長遠」的狀態。
FAQ 常見問題
最後,我們來解答幾個開發者常見的疑問,加深對 localStorage 和 sessionStorage 的理解。
答:就同一網域的頁面而言,localStorage 儲存的資料可以跨頁面、跨分頁視窗存取,共用程度高;而 sessionStorage 則無法在不同分頁間直接分享資料。具體來說,localStorage 是以網域為單位的全域儲存,只要是同一網站(同樣的網域和協議),在任何分頁打開,都能讀到相同的 localStorage 資料。這意味著你可以利用 localStorage 在不同頁面之間傳遞資訊,例如在主頁儲存一些狀態,然後在子頁面讀取。另外,localStorage 還有一個特性:當一個分頁中的 localStorage 資料改變時,同網域下其他分頁會觸發 "storage" 事件,開發者可以監聽這個事件來同步狀態,例如在一個分頁登出時自動讓另一個分頁也登出。
反觀 sessionStorage,它的資料域僅限於單一分頁。每當你開啟一個新的瀏覽器分頁或視窗,即便 URL 相同,都會創建一個全新的 sessionStorage 空間,預設情況下彼此獨立。因此,一個分頁中的 sessionStorage 資料無法被另一個分頁直接存取。唯一特殊的情況是透過特定方式打開新頁(例如從原頁點擊連結開新標籤且未使用 noopener),新頁可能複製原頁的 sessionStorage 初始資料,但後續兩者之間並不同步。總而言之,當你需要在多頁面共享資料時,localStorage 是更好的選擇;而如果資料不應跨頁共用,就可以放進 sessionStorage 裡。當然,兩者都無法跨不同網域分享資料——網域間的存取限制是由瀏覽器安全策略嚴格把關的。
答:簡而言之,依據資料需要保存的時間長短和作用範圍來決定:
選擇 localStorage:當資料需要長期保存,或需要在使用者多次造訪網站時仍然可用,就適合使用 localStorage。例如:使用者的偏好設定(主題顏色、語言選擇)、記住登入狀態或 JWT 憑證、購物車內容、長期的統計資訊等等。localStorage 也適合用來在同網域的不同頁面間傳遞資料,因為所有頁面共享同一套資料。例如,你可以用 localStorage 在多個頁面之間共享使用者的設定,而不需要每個頁面都重新從伺服器抓取一次。需要注意的是,localStorage 沒有過期時間的概念,資料會一直保存,所以如果有些資料只在一定時間內有效,你需要自行實作機制(例如儲存時一併寫入時間戳,讀取時判斷是否過期)或在適當時機清除,避免使用者瀏覽器累積太多過期資訊。
選擇 sessionStorage:當資料只在當前使用過程中有用,不需要持久保存到下次訪問時,就可以考慮用 sessionStorage。例如:表單的臨時輸入內容、一次性閱讀通知的狀態、當前頁面的 UI 狀態(展開或折疊的面板狀態)等。sessionStorage 能確保這些資料在使用者關閉分頁後自動清除,減少後續頁面受到陳舊資料干擾的可能。同時,由於 sessionStorage 不會在不同頁面共享,你可以放心地在其中存放一些僅與當前情境相關的資訊,而不必擔心它"溢出"到別的頁面。例如,在一個多步驟表單流程中,你可以用 sessionStorage 暫存用戶在第一步輸入的內容,待流程完成或取消時再清掉。在用戶開啟另一個新分頁重新走流程時,不會受到之前那個分頁殘留資料的影響。
總的來說,如果你希望資料持久、跨頁且廣泛,選擇 localStorage;如果資料短暫、侷限於當前視窗,選擇 sessionStorage。在實務上,兩者也可以混合使用:需要長存的用 localStorage,需要短存的用 sessionStorage,各取所長。
答:把資料存在使用者的瀏覽器端,本質上是純前端的行為,這對安全性的影響需要從多個角度來看:
同源隔離與資料隱私:如前所述,localStorage 和 sessionStorage 採取同源策略,其他網域的網站無法讀取你的儲存資料,這點是安全的,不用擔心A網站偷看到B網站存在使用者瀏覽器裡的資訊。此外,這些資料只存在用戶端,不會自動傳給伺服器或第三方,某種程度上保障了使用者的資料隱私(除非使用者自行洩漏或裝了惡意外掛程式)。
XSS 攻擊風險:然而,更大的風險在於前端程式碼本身的安全性。如果你的网站存在跨站腳本攻擊(XSS)漏洞,攻擊者有機會注入惡意腳本到你的網頁,那麼這段腳本就可以讀取使用者瀏覽器中的 localStorage/sessionStorage 資料,將其中的敏感資訊(如登入 token、個人資料)竊取並傳送給攻擊者。換句話說,儲存在 Web Storage 中的資料並非加密的機密,任何在該網域上下文執行的腳本都能存取它們。所以,如果存放的是敏感資訊(比如身份驗證令牌、信用卡資訊等),一定要確保網站沒有 XSS 漏洞,否則等於將這些資料暴露給潛在攻擊。而即使沒有惡意攻擊者,開發者在瀏覽器控制台也能輕易讀寫 localStorage/sessionStorage,因此切勿將密碼等機敏資料以純文字形式長期存放在裡頭。
與 Cookie 比較安全性:有些人會問,那相比將資料存在 Cookie(特別是設置了 HttpOnly 屬性的 Cookie)哪個比較安全?Cookie 若標記了 HttpOnly,則前端 JavaScript 無法讀取,反而避免了 XSS 獲取敏感資訊的風險。因此,很多應用選擇將重要的身份令牌存在 HttpOnly Cookie 中,而不是存在 localStorage。但 Cookie 會自動附加在每個請求中,容易受到 CSRF 攻擊,如果沒有妥善防護(例如使用 SameSite 屬性或 anti-CSRF token)。所以安全性沒有絕對孰優孰劣,而是要看你面臨的威脅模型:如果擔心 XSS,就避免把關鍵憑證放在 localStorage;如果擔心 CSRF,就要小心 Cookie 的使用。總之,在使用 Web Storage 時,要對敏感資料加強保護——例如加密後再存,或存一些對攻擊者意義不大的資訊。
裝置端安全:最後,資料是保存在使用者的裝置上,這意味着如果別人能夠直接存取該裝置(例如共用電腦、遺失的手機),他可以透過瀏覽器查看 localStorage/sessionStorage 的內容。因此在公共或不信任的裝置上,敏感資料更是不可掉以輕心。某些瀏覽器提供無痕模式(隱私模式),在此模式下 Web Storage 會在瀏覽器關閉後清除,是提升安全的一種手段。如果你的網頁可能在公用電腦上使用,務必要提醒用戶登出時清除資料,或者乾脆不要在 localStorage 保存過久的登入狀態。
總結:localStorage 和 sessionStorage 在機制上是安全的,不會被其他網域隨意存取,而且使用上也很便利。但真正決定安全性的是你的使用方式。對於一般不太敏感的資料(偏好設定、介面狀態等),儲存在 Web Storage 中問題不大;對於敏感資訊,一定要權衡便利性與風險,必要時採取額外的防護措施或考慮其他更安全的存儲方案。
結論
localStorage 和 sessionStorage 作為前端開發者的好幫手,各自扮演著不同的角色:一個負責長期記憶,讓網站對使用者來說更貼心、更持久;一個注重短期暫存,保障使用體驗的同時保持資料的新鮮與私密。在這篇教學中,我們探討了它們的原理與差異,也透過登入狀態、購物車、SPA 草稿等實例演練了如何在適當的情境選擇適當的儲存方式。
對具備中階 JavaScript 能力的你而言,善用 Web Storage 可以大幅提升前端應用的體驗。但也別忘了,每種技術都有其局限和需要注意的地方:容量有限就避免肆意存放海量資料,永久保存就記得考慮資料更新與清理,方便易取也要顧及安全與隱私。希望這篇文章讓你對 localStorage 和 sessionStorage 有了更全面、深入的理解,在未來的開發中能夠游刃有餘地運用它們,打造既便利又安全的網頁應用!