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

