JavaScript本地存儲(chǔ)的方式總結(jié)大全
名稱 | 是什么 | 用途 | 特點(diǎn) |
|---|---|---|---|
??Session(會(huì)話)?? | 服務(wù)端存儲(chǔ)的一段用戶會(huì)話信息,通常用 ??Session ID?? 來標(biāo)識(shí) | 用于識(shí)別用戶是否已登錄、保存登錄狀態(tài) | 服務(wù)端存儲(chǔ),有狀態(tài),適合傳統(tǒng)服務(wù)端渲染應(yīng)用 |
??Cookie?? | 瀏覽器存儲(chǔ)的一種小型文本數(shù)據(jù),隨每次 HTTP 請(qǐng)求自動(dòng)發(fā)送給服務(wù)端 | 通常用來存儲(chǔ) ??Session ID?? 或 ??Token??,用于維持登錄狀態(tài) | 客戶端存儲(chǔ),可設(shè)置 HttpOnly、Secure 等安全屬性 |
??JWT (JSON Web Token)?? | 一種自包含的、標(biāo)準(zhǔn)化的 Token 格式,用于身份認(rèn)證,包含用戶信息 | 通常用于前后端分離、API 鑒權(quán),服務(wù)端無需存儲(chǔ)用戶狀態(tài) | 無狀態(tài),可攜帶用戶信息,客戶端存儲(chǔ)或通過 Cookie 傳遞 |
維度 | ??Session?? | ??Cookie?? | ??JWT Token?? |
|---|---|---|---|
??存儲(chǔ)位置?? | 服務(wù)端(Session 數(shù)據(jù)) | 客戶端(瀏覽器) | 客戶端(通常是 localStorage 或 Cookie) |
??標(biāo)識(shí)用戶的方式?? | 通過 ??Session ID(存在 Cookie 或 URL)?? 找到服務(wù)端存儲(chǔ)的會(huì)話數(shù)據(jù) | 本身不認(rèn)證用戶,通常 ??存儲(chǔ) Session ID 或 Token?? | Token 自身包含用戶信息(Payload),無需服務(wù)端存儲(chǔ) |
??有無狀態(tài)?? | 有狀態(tài)(服務(wù)端要存 Session) | 無狀態(tài)(本身只是存儲(chǔ)機(jī)制) | 無狀態(tài)(JWT 自包含信息) |
??適用場(chǎng)景?? | 傳統(tǒng)服務(wù)端渲染應(yīng)用(如 PHP、老 Java Web) | 用于存儲(chǔ) Session ID、Token 等 | 前后端分離、API 鑒權(quán)、移動(dòng)端、微服務(wù) |
??安全性注意點(diǎn)?? | Session ID 要防泄露,推薦用 HttpOnly + Secure Cookie | 若存敏感信息需加密,注意 XSS/CSRF | JWT 本身不加密,注意不要放敏感信息,防止泄露和劫持 |
JS 本地存儲(chǔ)的常見方式
1. ??Cookie
??Cookie 是存儲(chǔ)在用戶瀏覽器端的一小段文本數(shù)據(jù),用于在客戶端和服務(wù)端之間保持狀態(tài)(比如用戶身份、登錄狀態(tài)、偏好設(shè)置等)。??某些網(wǎng)站為了辨別用戶身份而儲(chǔ)存在用戶本地終端上的數(shù)據(jù)。是為了解決
HTTP無狀態(tài)導(dǎo)致的問題。
??Cookie 本身不認(rèn)證用戶,它通常只是個(gè)“載體”??
可以存 ??Session ID??(傳統(tǒng)方式,服務(wù)端查 Session)
也可以存 ??JWT Token??(現(xiàn)代方式,服務(wù)端或前端解析 Token)
??瀏覽器每次訪問網(wǎng)站時(shí),會(huì)自動(dòng)把 Cookie 發(fā)給服務(wù)端,服務(wù)端根據(jù)里面的 ID 或 Token 來識(shí)別用戶??
? ??Cookie 是橋梁,真正區(qū)分用戶的是 Session 或 JWT??
由 ??服務(wù)端通過 HTTP 響應(yīng)頭 Set-Cookie設(shè)置??
瀏覽器后續(xù)請(qǐng)求會(huì)自動(dòng)通過 ??HTTP 請(qǐng)求頭 Cookie把匹配的 Cookie 發(fā)回給服務(wù)端??
常用于 ??會(huì)話管理(Session)、身份認(rèn)證(如登錄態(tài))、個(gè)性化設(shè)置、跟蹤等??
存的一般是:
一個(gè)
sessionId的唯一標(biāo)識(shí)符或者 JWT一般不會(huì)直接把用戶信息(如密碼、用戶對(duì)象)存在 Cookie 中 ?(不安全)
? 特點(diǎn):
存儲(chǔ)在瀏覽器中,??每次 HTTP 請(qǐng)求都會(huì)自動(dòng)攜帶??(在請(qǐng)求頭
Cookie字段中)。如果不使用HTTPS并對(duì)其加密,其保存的信息很容易被竊取,導(dǎo)致安全風(fēng)險(xiǎn)。舉個(gè)例子,在一些使用
cookie保持登錄態(tài)的網(wǎng)站上,如果cookie被竊取,他人很容易利用你的cookie來假扮成你登錄網(wǎng)站,標(biāo)記為Secure的Cookie就是通過被HTTPS協(xié)議加密過的請(qǐng)求發(fā)送給服務(wù)端??容量較小??:每個(gè) Cookie 通常不超過 ??4KB??,一個(gè)域名下一般限制在 ??20~50 個(gè) Cookie??。
不適合存儲(chǔ)大數(shù)據(jù)并且每次 HTTP 請(qǐng)求都會(huì)攜帶 Cookie,如果 Cookie 太多或太大,會(huì)增加請(qǐng)求頭大小,影響性能。
??有過期時(shí)間??:可以設(shè)置過期時(shí)間(Expires / Max-Age 優(yōu)先級(jí)更高)。
Expires 用于設(shè)置 Cookie 的過期時(shí)間
Max-Age 用于設(shè)置在 Cookie 失效之前需要經(jīng)過的秒數(shù)
??可設(shè)置作用域??:通過
Domain和Path控制哪些路徑/域名可以訪問。? 用途:傳統(tǒng)用于身份驗(yàn)證(如 Session ID)、用戶跟蹤。
但??不適合存儲(chǔ)大量數(shù)據(jù)??,且有隱私和安全問題(如 CSRF)。
?? 示例:
// 設(shè)置 cookie document.cookie = "username=JohnDoe; expires=Thu, 18 Dec 2024 12:00:00 UTC; path=/"; // 讀取 cookie(需自己解析) console.log(document.cookie); // username=JohnDoe; otherKey=value... // 刪除 cookie(設(shè)置過期時(shí)間為過去) document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
有哪些字段?
字段 | 是否必填 | 作用 | 是否可前端設(shè)置 | 常見值/說明 |
|---|---|---|---|---|
??Name?? | ? | Cookie 名稱 | ? | 如 |
??Value?? | ? | Cookie 值 | ? | 如 |
??Expires?? | ? | 過期時(shí)間(絕對(duì)時(shí)間 GMT) | ?(有限制) |
|
??Max-Age?? | ? | 過期時(shí)間(相對(duì)秒數(shù)) | ?(有限制) |
|
??Domain?? | ? | 作用域名(如 | ?(僅服務(wù)端) |
|
??Path?? | ? | 作用路徑(如 | ? |
|
??Secure?? | ? | 僅 HTTPS 傳輸 | ? | 用于安全傳輸 |
??HttpOnly?? | ? | 無法通過 JS 訪問,防止 XSS 攻擊竊 取 Cookie。 | ?(僅服務(wù)端) | 提升安全性 |
??SameSite?? | ? | 防 CSRF,控制跨站發(fā)送 控制該 Cookie 在跨站點(diǎn)請(qǐng)求(時(shí)是否會(huì)被瀏覽器自動(dòng)發(fā)送 | ?(僅服務(wù)端) |
|
| 值 | 含義 | 是否允許跨站發(fā)送 Cookie | 適用場(chǎng)景 | 是否必須 Secure |
|---|---|---|---|---|
Strict | 僅限當(dāng)前站點(diǎn)請(qǐng)求攜帶 Cookie,完全禁止跨站發(fā)送? | ? 不允許 | 高安全需求(如銀行) | ? 否 |
Lax(默認(rèn)) | 允許安全的跨站請(qǐng)求(如導(dǎo)航跳轉(zhuǎn))攜帶,阻止多數(shù)跨站 POST/AJAX 請(qǐng)求? | ? 部分允許 | 推薦大多數(shù)網(wǎng)站使用 | ? 否 |
None | **允許所有跨站請(qǐng)求攜帶 Cookie(包括 POST / iframe / 跨域 API)**? | ? 允許 | 跨域登錄、嵌入第三方、SSO | ? 必須同時(shí)設(shè)置 Secure(僅 HTTPS) |
前端如何查看 Cookie?
在瀏覽器中:
打開 ??開發(fā)者工具(F12)→ Application → Cookies??
或者直接在 Console 里輸入:
document.cookie(但只能獲取非 HttpOnly 的 Cookie)
?? ??注意:如果 Cookie 設(shè)置了 HttpOnly,前端 JS 是無法通過 document.cookie讀取的!??
如何設(shè)置 Cookie?
document.cookie手動(dòng)設(shè)置一個(gè)簡(jiǎn)單的 Cookie(但無法設(shè)置 HttpOnly / Secure 等服務(wù)端專屬字段):
document.cookie = "username=John; expires=Thu, 18 Dec 2025 12:00:00 UTC; path=/";
更復(fù)雜的屬性(如 HttpOnly、Secure、Domain)??只能由服務(wù)端(后端)通過 HTTP 響應(yīng)頭 Set-Cookie 設(shè)置??
當(dāng)服務(wù)端響應(yīng)時(shí),通過 HTTP 響應(yīng)頭設(shè)置 Cookie,格式如下:
Set-Cookie: Name=Value; Expires=date; Path=/; Domain=.example.com; Secure; HttpOnly; SameSite=Lax
?? 這是一個(gè)完整的 Cookie 設(shè)置示例,包含多個(gè) ??字段(屬性)??,每個(gè)字段都是 ??鍵值對(duì)形式,用分號(hào) ;分隔??。
刪除cookie:設(shè)置和目標(biāo)cookie相同的key,path,domain,只是把expires設(shè)置成過去的時(shí)間,瀏覽器自動(dòng)刪除過期的cookie。
Cookie 本身可以包含中文,但需要正確編碼,否則會(huì)出現(xiàn)亂碼或設(shè)置失敗。使用 encodeURIComponent對(duì)中文進(jìn)行編碼,讀取時(shí)用 decodeURIComponent解碼。
原因:? Cookie 的值(Value)本質(zhì)上是一個(gè)字符串,但由于 HTTP 協(xié)議和 Cookie 規(guī)范要求其內(nèi)容必須是 合法 ASCII 或經(jīng)過編碼的字符串,如果你直接設(shè)置含有中文的 Cookie 值,比如:
document.cookie = "username=張三"; // 可能出錯(cuò)或亂碼
瀏覽器或服務(wù)器可能無法正確解析,導(dǎo)致存儲(chǔ)失敗或亂碼。
? 子域名如何訪問主域名的 Cookie?
設(shè)置Cookie 的作用域(Domain 和 Path) 他倆控制著哪些域名/路徑可以訪問該 Cookie。
注意 domain前面要加 點(diǎn)(.),表示該 Cookie 可被主域名及所有子域名共享。
默認(rèn)情況下:
如果你在
www.example.com下設(shè)置了一個(gè) Cookie 沒有特別指定 domain,那么這個(gè) Cookie 只能被 www.example.com訪問,子域名如 blog.example.com 是無法訪問的!你需要在設(shè)置 Cookie 時(shí),顯式指定 Cookie 的 domain 為主域名(不帶 www 或子域名),通常為
.example.com(注意前面的點(diǎn) . )?? 示例:在主域名下設(shè)置一個(gè)子域名可訪問的 Cookie
// 假設(shè)當(dāng)前是主域名 www.example.com 或 api.example.com document.cookie = `token=abc123; domain=.example.com; path=/; max-age=3600`;
domain=.example.com:表示該 Cookie 可以被example.com及所有它的子域名(如blog.example.com、shop.example.com)訪問。
path=/:表示整個(gè)域名下所有路徑都可訪問該 Cookie。
max-age=3600:有效期為 1 小時(shí)(單位秒)?? 注意:
domain必須是你當(dāng)前域名所屬的父域名,你不能設(shè)置一個(gè)你控制之外的域名? 的 cookie(出于安全限制)。
Cookie 和 Token 的區(qū)別?
Cookie:? 是瀏覽器提供的一種 “自動(dòng)夾帶的東西”,只要瀏覽器發(fā)現(xiàn)你要訪問同域下的網(wǎng)站,就會(huì)把這個(gè)(Cookie)自動(dòng)塞進(jìn)請(qǐng)求頭里,適合做傳統(tǒng)的登錄態(tài)保持,但有 CSRF 風(fēng)險(xiǎn)。
如果你的 token 或 session id 是通過 Set-Cookie? 由服務(wù)端下發(fā),并且存儲(chǔ)在瀏覽器的 Cookie 中,那么 瀏覽器會(huì)在后續(xù)同域請(qǐng)求中自動(dòng)把 Cookie 附加到請(qǐng)求頭(Cookie: xxx)里,無需手動(dòng)處理。
? 優(yōu)點(diǎn):自動(dòng)管理,適合保持登錄態(tài),尤其對(duì)傳統(tǒng)服務(wù)端應(yīng)用友好
? 缺點(diǎn):受 SameSite 限制,跨域攜帶麻煩;有 CSRF 攻擊風(fēng)險(xiǎn)(可通過SameSite=Lax/Strict + CSRF Token 防范)
=====================================
Token:? 是你自己生成的一張 “身份證/令牌”,你需要 手動(dòng)把它交給服務(wù)器(通常放在請(qǐng)求頭里,如 Authorization: Bearer xxx),適合現(xiàn)代 SPA、跨域 API 場(chǎng)景,更靈活但需要自己管理安全性(防 XSS)。
如果你把 token(比如 JWT)存在
localStorage或sessionStorage,那么每次發(fā)起 HTTP 請(qǐng)求時(shí)(比如調(diào)用 API),你需要手動(dòng)從 storage 中取出 token,然后加到請(qǐng)求頭里,Token(尤其是 JWT)可以攜帶豐富的信息,比如用戶 ID、角色、權(quán)限、過期時(shí)間等,不需要每次都查詢數(shù)據(jù)庫,適合分布式系統(tǒng)、微服務(wù)、跨平臺(tái)身份驗(yàn)證。
服務(wù)端只需校驗(yàn) JWT 的簽名與有效期,即可識(shí)別用戶身份與權(quán)限,非常適合 現(xiàn)代前后端分離架構(gòu)、移動(dòng)端 App、第三方登錄、SSO 等復(fù)雜場(chǎng)景。
- ? 優(yōu)點(diǎn):存儲(chǔ)靈活,可存復(fù)雜信息,適合跨域、多系統(tǒng)共享 token
? 缺點(diǎn):需要手動(dòng)管理,容易因忘記添加而導(dǎo)致鑒權(quán)失敗;存在 XSS 攻擊風(fēng)險(xiǎn)(惡意腳本可讀取 localStorage)
很多大型系統(tǒng)會(huì)采用如下混合模式:
用 Cookie 存一個(gè) CSRF Token(只讀,不用于身份認(rèn)證)
用 Token(JWT)做身份認(rèn)證,存在 localStorage 或內(nèi)存,手動(dòng)加到請(qǐng)求頭
或者用 HttpOnly + Secure 的 Cookie 存 JWT(更安全,防止 XSS 讀?。?/span>,但此時(shí)仍需服務(wù)端配合設(shè)置 Cookie,前端無法直接讀取
對(duì)比維度 | Cookie? | Token(通常是 JWT)? |
|---|---|---|
存儲(chǔ)位置? | 瀏覽器自動(dòng)管理,存儲(chǔ)在瀏覽器 Cookie 中 | 一般由前端手動(dòng)存儲(chǔ),比如存在 |
發(fā)送方式? | 瀏覽器會(huì)在每次向 同域/同站點(diǎn)? 發(fā)請(qǐng)求時(shí),自動(dòng)在 HTTP Header(Cookie: xxx)中攜帶? | 需要開發(fā)者 手動(dòng)將 token 放入請(qǐng)求頭,如:Authorization: Bearer <token>? |
自動(dòng)攜帶? | ? 對(duì)同域請(qǐng)求自動(dòng)攜帶(受 SameSite 和 Secure 等限制) | ? 必須手動(dòng)添加,比如在 axios 攔截器中統(tǒng)一加 header |
跨域支持? | 受限于 SameSite、CORS、Secure 等策略,跨域攜帶較復(fù)雜 | 更靈活,只要后端允許 CORS 并校驗(yàn) token,就能用于跨域身份驗(yàn)證 |
CSRF 風(fēng)險(xiǎn)? | 有 CSRF 風(fēng)險(xiǎn)(因?yàn)樽詣?dòng)攜帶,攻擊者可偽造請(qǐng)求) | 無 CSRF 風(fēng)險(xiǎn)(不會(huì)自動(dòng)發(fā)送,但要注意 XSS 攻擊導(dǎo)致 token 泄露) |
適用場(chǎng)景? | 傳統(tǒng)服務(wù)端渲染應(yīng)用、同域登錄態(tài)保持 | 現(xiàn)代前后端分離、跨域 API 請(qǐng)求、移動(dòng)端/單頁應(yīng)用(SPA) |
復(fù)雜身份驗(yàn)證支持? | 一般,依賴服務(wù)端 session 管理 | 更靈活,可以存儲(chǔ)額外信息(如用戶角色、權(quán)限),適合復(fù)雜權(quán)限體系 |
? 最佳實(shí)踐建議(結(jié)合你的業(yè)務(wù)場(chǎng)景選擇)
場(chǎng)景 | 推薦方案 |
|---|---|
傳統(tǒng)網(wǎng)站(服務(wù)端渲染、同域、簡(jiǎn)單登錄) | 使用 Cookie + Session,簡(jiǎn)單易用,自動(dòng)攜帶 |
前后端分離 / SPA / 跨域 API | 使用 Token(如 JWT),存 localStorage / 內(nèi)存,手動(dòng)加請(qǐng)求頭 |
需要跨子域共享登錄態(tài) | 用 Cookie,并設(shè)置 |
高安全性要求,防 CSRF | 用 Cookie + SameSite + CSRF Token,或使用 Token 并防范 XSS |
想存儲(chǔ)中文或結(jié)構(gòu)化信息 | Token(如 JWT payload 中可存中文)更靈活,Cookie 需編碼 |
2. ??LocalStorage(本地存儲(chǔ))??
LocalStorage 能跨瀏覽器共享嗎??? | ? 不能,LocalStorage 是瀏覽器級(jí)別的隔離,不同瀏覽器(Chrome/Firefox/Safari)之間無法共享 |
??LocalStorage 能跨標(biāo)簽頁共享嗎??? | ? 可以,只要是在同一個(gè)瀏覽器、同一個(gè)源(協(xié)議+域名+端口)下的標(biāo)簽頁,就能共享 |
??LocalStorage 會(huì)過期嗎??? | ? 不會(huì)自動(dòng)過期,除非手動(dòng)刪除、調(diào)用 clear(),或用戶清除瀏覽器數(shù)據(jù) |
??LocalStorage 和 Cookie 有什么區(qū)別??? | 容量、是否自動(dòng)發(fā)送到服務(wù)器、生命周期、安全性等都不同(可展開對(duì)比表) |
??如何實(shí)現(xiàn)跨瀏覽器或跨設(shè)備的數(shù)據(jù)同步??? | 不能依賴 LocalStorage,一般要通過 后端數(shù)據(jù)庫 + 用戶登錄態(tài) + 前端同步機(jī)制(如登錄后拉取用戶配置) |
? 特點(diǎn):
生命周期:??持久化存儲(chǔ)??,數(shù)據(jù)??不會(huì)隨著瀏覽器關(guān)閉而消失??,除非手動(dòng)刪除。
當(dāng)本頁操作(新增、修改、刪除)了
localStorage的時(shí)候,本頁面不會(huì)觸發(fā)storage事件,但是別的頁面會(huì)觸發(fā)storage事件。??存儲(chǔ)容量較大??:一般為 ??5MB~10MB??(不同瀏覽器可能略有差異)。
??僅支持字符串類型??,存儲(chǔ)對(duì)象需用
JSON.stringify()和JSON.parse()轉(zhuǎn)換。??同源策略??:只能在??相同協(xié)議、域名、端口??下訪問。
??不自動(dòng)發(fā)送到服務(wù)器??,僅在客戶端使用。
??任何 JS 代碼(包括惡意腳本、XSS 攻擊)都能讀取它們??,沒有 HttpOnly 保護(hù)。
如果網(wǎng)站存在 XSS 漏洞,攻擊者可以輕松通過
localStorage.getItem()獲取你的數(shù)據(jù)。??所以不適合存儲(chǔ)??:用戶的密碼、Token(尤其長期有效的)、身份信息等敏感數(shù)據(jù)。缺點(diǎn):
- 無法像
Cookie一樣設(shè)置過期時(shí)間 - 只能存入字符串,無法直接存對(duì)象
? 用途:
保存用戶主題設(shè)置、語言偏好、表單草稿、緩存數(shù)據(jù)等。
??適合存儲(chǔ)??:用戶主題、語言偏好、表單草稿、緩存的數(shù)據(jù)(如 JSON 配置)。
適合存儲(chǔ)??非敏感、長期保存??的數(shù)據(jù)。
?? 示例:
// 存數(shù)據(jù)
localStorage.setItem('username', 'Alice');
// 取數(shù)據(jù)
const user = localStorage.getItem('username'); // 'Alice'
// 刪除某個(gè) key
localStorage.removeItem('username');
// 清空所有 localStorage
localStorage.clear();LocalStorage 本身??沒有過期機(jī)制??,但你可以手動(dòng)實(shí)現(xiàn),例如:
// 存儲(chǔ)時(shí)帶上時(shí)間戳
const data = { value: 'hello', expires: Date.now() + 1000 * 60 * 60 }; // 1小時(shí)后過期
localStorage.setItem('myData', JSON.stringify(data));
// 取的時(shí)候判斷是否過期
const stored = JSON.parse(localStorage.getItem('myData'));
if (stored && stored.expires > Date.now()) {
console.log(stored.value); // 未過期
} else {
localStorage.removeItem('myData'); // 已過期,刪除
}3. ??SessionStorage(會(huì)話存儲(chǔ))??
? 特點(diǎn):
sessionStorage和localStorage使用方法基本一致,唯一不同的是生命周期,一旦頁面(會(huì)話)關(guān)閉,sessionStorage將會(huì)刪除數(shù)據(jù)?容量與 LocalStorage 類似(約 5MB)??。
??同樣僅支持字符串,同源策略限制??。
不同標(biāo)簽頁之間??不能共享??(即使域名一樣)。
? 用途:
適合存儲(chǔ)??當(dāng)前會(huì)話的臨時(shí)數(shù)據(jù)??,比如表單填寫中途的數(shù)據(jù)、當(dāng)前頁面狀態(tài)等。
?? 示例:
// 存數(shù)據(jù)
sessionStorage.setItem('tempData', '12345');
// 取數(shù)據(jù)
const data = sessionStorage.getItem('tempData');
// 刪除 / 清空 同 localStorage
sessionStorage.removeItem('tempData');
sessionStorage.clear();4. ??IndexedDB(索引數(shù)據(jù)庫)??
? 特點(diǎn):
是瀏覽器提供的??低級(jí)、異步、事務(wù)型數(shù)據(jù)庫??,基于 ??NoSQL(鍵值對(duì)或?qū)ο蟠鎯?chǔ))??。
??存儲(chǔ)容量大(一般幾十MB甚至更多)??,適合存儲(chǔ)大量結(jié)構(gòu)化數(shù)據(jù)。
??支持索引、事務(wù)、查詢等高級(jí)功能??,類似小型數(shù)據(jù)庫。
??異步 API(使用 Promise 或回調(diào))??,不會(huì)阻塞主線程。
??同源策略限制??。
? 用途:
適合存儲(chǔ)??大量結(jié)構(gòu)化數(shù)據(jù)??,如離線應(yīng)用數(shù)據(jù)、用戶生成的文件、復(fù)雜緩存等。
比 LocalStorage 更強(qiáng)大,但??使用較復(fù)雜??。
?? 示例(簡(jiǎn)化,實(shí)際通常封裝或使用庫如 idb、Dexie.js):
// 打開或創(chuàng)建數(shù)據(jù)庫
const request = indexedDB.open('myDatabase', 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('users')) {
db.createObjectStore('users', { keyPath: 'id' });
}
};
request.onsuccess = (event) => {
const db = event.target.result;
const tx = db.transaction('users', 'readwrite');
const store = tx.objectStore('users');
store.add({ id: 1, name: 'Alice' });
};5. ??Service Worker
? 特點(diǎn):
主要用于??離線緩存??,和 ??Service Worker?? 配合使用。
可以緩存??請(qǐng)求和響應(yīng)??,實(shí)現(xiàn)離線訪問(PWA 的關(guān)鍵技術(shù)之一)。
存儲(chǔ)的是網(wǎng)絡(luò)請(qǐng)求資源,如 HTML、JS、CSS、圖片等。
一般不直接用來存普通業(yè)務(wù)數(shù)據(jù)。
? 用途:
實(shí)現(xiàn)??離線網(wǎng)頁、漸進(jìn)式 Web 應(yīng)用(PWA)??
緩存 API 請(qǐng)求、靜態(tài)資源,提升二次訪問速度
區(qū)別表格
特性 | Cookie | LocalStorage | SessionStorage |
|---|---|---|---|
??容量?? | ~4KB | ~5~10MB | ~5~10MB |
??生命周期?? | 可設(shè)置過期時(shí)間,否則隨瀏覽器關(guān)閉(但通常用于會(huì)話) | 永久存儲(chǔ),除非手動(dòng)刪除 | 當(dāng)前標(biāo)簽頁關(guān)閉后自動(dòng)清除 |
??是否自動(dòng)發(fā)送到服務(wù)器?? | ? 每次 HTTP 請(qǐng)求都會(huì)帶上(在 Cookie 頭中) | ? 僅在客戶端 | ? 僅在客戶端 |
??作用域?? | 可設(shè)置 Domain / Path,可跨標(biāo)簽頁共享 | 同源下共享,跨標(biāo)簽頁共享 | 同源下共享,但??不同標(biāo)簽頁不共享?? |
??數(shù)據(jù)類型?? | 字符串 | 字符串(需手動(dòng) JSON 序列化) | 字符串(需手動(dòng) JSON 序列化) |
??典型用途?? | 身份驗(yàn)證(Session ID)、用戶跟蹤 | 用戶偏好、緩存數(shù)據(jù) | 當(dāng)前頁面臨時(shí)數(shù)據(jù) |
如何選擇IndexedDB/ LocalStorage
特性 | LocalStorage | IndexedDB |
|---|---|---|
??容量?? | 較?。?~10MB) | 更大(幾十MB甚至更多) |
??數(shù)據(jù)類型?? | 只能存字符串 | 可存對(duì)象、二進(jìn)制、結(jié)構(gòu)化數(shù)據(jù) |
??查詢能力?? | 無,只能按鍵存取 | 支持索引、事務(wù)、復(fù)雜查詢 |
??API?? | 同步(簡(jiǎn)單易用) | 異步(使用 Promise / 回調(diào),較復(fù)雜) |
??用途?? | 簡(jiǎn)單配置、偏好存儲(chǔ) | 大量數(shù)據(jù)、離線應(yīng)用、復(fù)雜緩存 |
?? ??什么時(shí)候用 IndexedDB???
當(dāng)你需要存儲(chǔ)??大量結(jié)構(gòu)化數(shù)據(jù)??(如離線博客文章、用戶筆記、文件緩存等)。
需要??查詢、排序、分頁等能力??,類似小型數(shù)據(jù)庫。
JWT 和 Session 的區(qū)別
JWT 和 Session 是兩種不同的用戶身份認(rèn)證機(jī)制:
1.Session 是需要用服務(wù)端存儲(chǔ)用戶登錄狀態(tài)的方案,需要依賴 Cookie 或 Session ID來實(shí)現(xiàn),服務(wù)端需要保存會(huì)話信息;
用戶登錄成功后,服務(wù)端會(huì)創(chuàng)建一個(gè) Session(會(huì)話)對(duì)象,保存用戶身份信息(如用戶 ID、權(quán)限等),并生成一個(gè)唯一的 Session ID,通常通過 Cookie? 返回給瀏覽器。之后,瀏覽器每次請(qǐng)求都會(huì)帶上這個(gè) Session ID(通常通過 Cookie: sessionId=xxx),服務(wù)端通過這個(gè) ID 找到對(duì)應(yīng)的 Session 數(shù)據(jù),確認(rèn)用戶身份。
2.JWT
它是一個(gè) 自包含的 Token,包含了用戶信息(payload),并由服務(wù)端進(jìn)行簽名,客戶端收到后保存(一般在 localStorage 或 Cookie),并在每次請(qǐng)求時(shí) 自行攜帶這個(gè) Token,服務(wù)端通過驗(yàn)證簽名來確認(rèn)其有效性,無需存儲(chǔ)用戶會(huì)話信息。
? 簡(jiǎn)單來說:Session 是服務(wù)端記住你,JWT 是你自己帶著證明(Token)去證明你是誰。
對(duì)比維度 | Session(會(huì)話)? | JWT(JSON Web Token)? |
|---|---|---|
狀態(tài)保存位置? | 服務(wù)端(Session 存儲(chǔ)用戶信息) | 客戶端(Token 自包含用戶信息) |
服務(wù)端是否需要存儲(chǔ)用戶狀態(tài)?? | ? 需要(如內(nèi)存、Redis) | ? 不需要(無狀態(tài)) |
客戶端存儲(chǔ)方式? | 通常通過 Cookie 傳遞 Session ID | 通常通過 Cookie / localStorage 存儲(chǔ) Token |
服務(wù)端驗(yàn)證方式? | 通過 Session ID 查找用戶信息 | 通過簽名驗(yàn)證 Token 是否合法 & 未過期 |
擴(kuò)展性(分布式支持)? | ? 需要額外處理 Session 共享(如 Redis) | ? 天然支持,無需共享狀態(tài) |
安全性? | ? 依賴 Cookie 安全設(shè)置(如 HttpOnly、Secure) | ? Token 泄露風(fēng)險(xiǎn)高(需設(shè)置短過期、HTTPS) |
登出 / 失效控制? | ? 服務(wù)端可主動(dòng)刪除 Session | ? 默認(rèn)無法主動(dòng)作廢(需額外邏輯如黑名單) |
適用場(chǎng)景? | 傳統(tǒng) Web 應(yīng)用,服務(wù)端渲染,集中式架構(gòu) | 現(xiàn)代前后端分離、移動(dòng)端、分布式系統(tǒng) |
Token 大小? | 小(僅 Session ID) | 較大(包含用戶信息的 JSON Token) |
? 2. JWT 的組成(三部分,用點(diǎn)號(hào) .分隔)
一個(gè) JWT Token 通常長這樣:
xxxxx.yyyyy.zzzzz
它由三部分組成:
Header(頭部):表明 Token 類型(JWT)和使用的加密算法(如 HS256、RS256)
Payload(負(fù)載):包含用戶信息(如用戶 ID、角色、過期時(shí)間等)—— 這是你存的信息
Signature(簽名):服務(wù)端用密鑰對(duì)前兩部分進(jìn)行簽名,防止被篡改
?? 服務(wù)端不保存這個(gè) Token,只負(fù)責(zé)生成和驗(yàn)證簽名!
? 3. JWT 的工作流程
用戶登錄
客戶端提交用戶名密碼
服務(wù)端驗(yàn)證成功,生成一個(gè) JWT Token(包含用戶 ID、過期時(shí)間等信息,用密鑰簽名)
服務(wù)端 返回 Token 給客戶端(通常放在響應(yīng)體里,如
{ token: "xxx.yyy.zzz" })
客戶端保存 Token
一般保存在 localStorage、sessionStorage 或 Cookie(HttpOnly 更安全)
客戶端后續(xù)請(qǐng)求
客戶端在請(qǐng)求頭(如
Authorization: Bearer <token>)中帶上 JWT Token服務(wù)端收到后,驗(yàn)證簽名和有效期,確認(rèn)用戶身份,無需查詢數(shù)據(jù)庫或 Session
登出 / 失效
JWT 本身是無狀態(tài)的,服務(wù)端通常 不主動(dòng)使其失效
想讓 Token 失效,一般通過:
設(shè)置短過期時(shí)間 + Refresh Token
黑名單機(jī)制(額外維護(hù)已失效的 Token)
選擇JWT 還是 Session?
場(chǎng)景 | 推薦方案 | 原因 |
|---|---|---|
? 傳統(tǒng) Web 應(yīng)用,服務(wù)端渲染(如 PHP、Java EE) | Session? | 服務(wù)端控制強(qiáng),生態(tài)成熟,安全性好 |
? 前后端分離、API 服務(wù)(如 Vue/React + Express/NestJS) | JWT? | 無狀態(tài),適合跨域、分布式,前端自主管理 Token |
? 移動(dòng)端 App、跨域接口 | JWT? | 無需依賴 Cookie,更適合 API 調(diào)用 |
? 需要服務(wù)端主動(dòng)踢人 / 控制登錄狀態(tài) | Session? | 服務(wù)端可隨時(shí)使 Session 失效 |
? 分布式系統(tǒng) / 微服務(wù)架構(gòu) | JWT? | 無需共享 Session,天然支持橫向擴(kuò)展 |
? JWT 的最佳實(shí)踐(安全增強(qiáng))
由于 JWT 默認(rèn)是無狀態(tài)的,為了提升安全性,通常會(huì):
2. 瀏覽器保存 Cookie,自動(dòng)發(fā)送
3. 服務(wù)端識(shí)別用戶身份
4. 用戶退出 / Session 過期
? 2. 服務(wù)端 Session 存在哪?
常見存儲(chǔ)方式:
存儲(chǔ)方式 | 說明 | 適用場(chǎng)景 |
|---|---|---|
??內(nèi)存(內(nèi)存對(duì)象)?? | 比如 Node.js 用一個(gè) Map 存 session,簡(jiǎn)單但不持久、重啟丟失 | 小項(xiàng)目 / 臨時(shí)方案 |
??Redis?? | 高性能 key-value 存儲(chǔ),適合存儲(chǔ)大量 session,支持過期 | 生產(chǎn)推薦 ? |
??數(shù)據(jù)庫(如 MySQL)?? | 可靠但性能較低,適合小型應(yīng)用 | 一般不推薦 |
??文件系統(tǒng)?? | 不常用,性能差 | 一般不推薦 |
設(shè)置短過期時(shí)間(如 15~30 分鐘)
使用 Refresh Token 機(jī)制刷新 Access Token
將 JWT 存在 HttpOnly 的 Cookie 中(防 XSS)
使用 HTTPS,防止 Token 被竊聽
可配合黑名單機(jī)制,使特定 Token 失效
使用session的完整流程
1. 用戶登錄
用戶在瀏覽器訪問登錄頁面,輸入用戶名和密碼,點(diǎn)擊登錄。
前端通過表單或 AJAX 把用戶名密碼發(fā)送到服務(wù)端(如 POST /login)。
??服務(wù)端驗(yàn)證用戶名密碼正確后:??
在服務(wù)端的內(nèi)存 / Redis / 數(shù)據(jù)庫中創(chuàng)建一個(gè) ??Session??,比如:
{ "sessionId": "abc123", "userId": 1001, "username": "Alice", "isLoggedIn": true, "expiresAt": "2024-06-30T10:00:00Z" }然后服務(wù)端生成一個(gè)唯一的 ??Session ID(比如 abc123)??,并通過 HTTP 響應(yīng)頭 ??
Set-Cookie: sessionId=abc123; Path=/; HttpOnly?? 把這個(gè) ID ??下發(fā)給瀏覽器,存入 Cookie。??
瀏覽器收到響應(yīng)后,會(huì)把
sessionId=abc123這個(gè) Cookie ??保存在本地(瀏覽器)??。之后,??只要訪問同一個(gè)域名(比如 example.com)下的任何頁面或接口,瀏覽器都會(huì)自動(dòng)在 HTTP 請(qǐng)求頭中帶上這個(gè) Cookie:??
Cookie: sessionId=abc123
(這是瀏覽器自動(dòng)做的,前端 JS 通常不需要關(guān)心)
當(dāng)用戶訪問首頁、個(gè)人資料等需要登錄的頁面時(shí),請(qǐng)求會(huì)帶上這個(gè) Cookie。
服務(wù)端收到請(qǐng)求后,會(huì)從 HTTP 請(qǐng)求頭中的
Cookie: sessionId=abc123提取出sessionId。然后去服務(wù)端存儲(chǔ)(比如 Redis / 內(nèi)存 / 數(shù)據(jù)庫)中查找
sessionId=abc123對(duì)應(yīng)的 ??Session 數(shù)據(jù)??。如果找到,并且未過期,服務(wù)端就知道:“哦,這個(gè)用戶是 Alice,已經(jīng)登錄了”,于是返回對(duì)應(yīng)的用戶頁面或數(shù)據(jù)。
用戶退出登錄時(shí),服務(wù)端可以:
刪除服務(wù)端存儲(chǔ)的
sessionId=abc123對(duì)應(yīng)的 session 數(shù)據(jù)或者讓這個(gè) session 過期
同時(shí),也可以選擇讓瀏覽器刪除對(duì)應(yīng)的 Cookie(比如設(shè)置過期時(shí)間為過去的時(shí)間)
之后用戶再訪問頁面,由于服務(wù)端找不到對(duì)應(yīng)的 Session,就會(huì)認(rèn)為用戶未登錄,跳轉(zhuǎn)到登錄頁
總結(jié)
到此這篇關(guān)于JavaScript本地存儲(chǔ)方式總結(jié)大全的文章就介紹到這了,更多相關(guān)JS本地存儲(chǔ)方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JS使用正則表達(dá)式實(shí)現(xiàn)常用的表單驗(yàn)證功能分析
這篇文章主要介紹了JS使用正則表達(dá)式實(shí)現(xiàn)常用的表單驗(yàn)證功能,結(jié)合實(shí)例形式分析了JS基于正則表達(dá)式的表單驗(yàn)證功能原理、實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2020-04-04
通過JAVAScript實(shí)現(xiàn)頁面自適應(yīng)
通過JAVAScript實(shí)現(xiàn)頁面自適應(yīng)...2007-01-01
JavaScript DOM實(shí)現(xiàn)簡(jiǎn)單留言板
這篇文章主要為大家詳細(xì)介紹了JavaScript DOM實(shí)現(xiàn)簡(jiǎn)單留言板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
JavaScript單線程實(shí)現(xiàn)異步的詳細(xì)代碼示例
瀏覽器JavaScript的作用是操作DOM,這就決定了它只能是單線程的,否則會(huì)帶來很復(fù)雜的問題,這篇文章主要介紹了JavaScript單線程實(shí)現(xiàn)異步的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-08-08
Javascript別踩白塊兒(鋼琴塊兒)小游戲?qū)崿F(xiàn)代碼
游戲唯一的一個(gè)規(guī)則,我們只需要不斷踩著黑色方塊前進(jìn)即可,這里根據(jù)方向鍵來踩白塊,在規(guī)定的時(shí)間內(nèi),每走一次分?jǐn)?shù)加100.下面通過本文給大家分享Javascript別踩白塊兒(鋼琴塊兒)小游戲?qū)崿F(xiàn)代碼,一起看看吧2017-07-07
vue+ts下對(duì)axios的封裝實(shí)現(xiàn)
這篇文章主要介紹了vue+ts下對(duì)axios的封裝實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
使用JavaScript?+?HTML5?Canvas實(shí)現(xiàn)互動(dòng)愛心雨完整代碼
canvas是HTML5中推出的新功能,可以在頁面上生成一個(gè)畫布,使用js可以在畫布上繪制一些圖形,這篇文章主要介紹了使用JavaScript?+?HTML5?Canvas實(shí)現(xiàn)互動(dòng)愛心雨的相關(guān)資料,需要的朋友可以參考下2025-03-03
JavaScript將字符串轉(zhuǎn)為base64的五種方法
這篇文章主要介紹了JavaScript將字符串轉(zhuǎn)為Base64的五種方法:ASCII用btoa,非ASCII需UTF-8編碼(encodeURIComponent或TextEncoder),Node.js用Buffer,URL安全需替換字符,第三方庫如js-base64提供更便捷功能,需要的朋友可以參考下2025-06-06

