面試時(shí)候經(jīng)常會(huì)被問(wèn)及 Cookie 大小限制,但一直沒(méi)嘗試寫(xiě)一些 demo 測(cè)試下溢出極限值會(huì)怎樣~~
本文就來(lái)看看各種極限情況!
英文
測(cè)試代碼:
(() => {
const maxSize = 4 * 1024;
const name = 'name'
const maxValueStr = 'a'.repeat(maxSize - name.length);
document.cookie = `${name}=${encodeURIComponent(maxValueStr)};expires=${new Date(2026, 0, 1).toUTCString()};path=/`;
})()
Chrome/Edge/Firefox 瀏覽器
英文:名字 + 內(nèi)容
字符串長(zhǎng)度限制 4096 字符。

各家瀏覽器的存儲(chǔ)面板都能看到 Cookie 大小,此大小包含存入 Cookie 的名字和內(nèi)容加在一起的長(zhǎng)度。
不同之處
Chrome/Edge
超過(guò) 4KB 大小無(wú)法存儲(chǔ),瀏覽器無(wú)報(bào)錯(cuò),也無(wú)提示,純粹毫無(wú)感知。
Firefox
超過(guò) 4KB 大小會(huì)有提示:
Cookie “name”太大而無(wú)效。最大大小為 4096 字節(jié)。
比如這段代碼存入 cookie 的值超過(guò)一個(gè)字符:
(() => {
const maxSize = 4 * 1024 - 5;
const maxStr = 'a'.repeat(maxSize) + 'b1';
console.log('?? ~ maxStr:', maxStr.length);
document.cookie = `name=${encodeURIComponent(maxStr)};expires=${new Date(2026, 0, 1).toUTCString()};path=/`;
})()
運(yùn)行有警告:

如果在 Firefox 中 localhost 使用 secure 會(huì)報(bào)錯(cuò)??!
由于非 HTTPS Cookie 無(wú)法設(shè)置“secure”屬性,已拒絕 Cookie “name”。
比如這段代碼在本地 localhost 的環(huán)境中 Chrome 和 Edge 都能正常運(yùn)行,但是 Firefox 會(huì)報(bào)錯(cuò):
document.cookie = `name=${encodeURIComponent(maxStr)};expires=${new Date(2026, 0, 1).toUTCString()};path=/;Secure;SameSite=Lax`;
報(bào)錯(cuò):

中文
一個(gè)中文占用3個(gè)英文長(zhǎng)度?。?!
測(cè)試代碼:
(() => {
const maxSize = 4 * 1024;
const name = 'name'
const valueSize = maxSize - name.length
console.log(valueSize / 3);
const value = '中'.repeat(Math.floor(valueSize / 3));
document.cookie = `name=${(value)};expires=${new Date(2026, 0, 1).toUTCString()};path=/`;
})()
4KB 字符串長(zhǎng)度減去 name 的長(zhǎng)度,除以 3 等于 1364 中文字符長(zhǎng)度,剛好是瀏覽器能存儲(chǔ)的極限值。
Firefox 顯示的大小比較另類,它沒(méi)按照轉(zhuǎn)換后的大小顯示,而是直接顯示了中文值長(zhǎng)度 + 英文名稱長(zhǎng)度,而 Chrome 和 Edge 顯示的是占用空間長(zhǎng)度。如下圖:

一般在存儲(chǔ)中文的的時(shí)候,會(huì)用到 encodeURIComponent
編碼一下中文字符,這方法編碼之后,一個(gè)中文字符將會(huì)轉(zhuǎn)成 9 個(gè)英文字符,使用這種方法存儲(chǔ)中文時(shí)候需特別注意?。?!

使用 cookieStore
cookieStore 存入超過(guò)大小限制的字符串長(zhǎng)度時(shí),會(huì)報(bào)一個(gè)奇奇怪怪的錯(cuò)誤,比如:
(async () => {
const maxSize = 4 * 1024;
const name = 'name'
const valueSize = maxSize - name.length
console.log(valueSize / 3);
const value = '中'.repeat(Math.floor(valueSize / 3));
const res = await cookieStore.set({
name: 'name',
value: value + '1',
expires: new Date(2026, 0, 1).getTime(),
path: '/',
sameSite: 'lax'
})
console.log('存儲(chǔ)結(jié)果:', res);
})()
報(bào)錯(cuò):

翻譯過(guò)來(lái)的大致意思:由于解析時(shí)出現(xiàn)問(wèn)題,導(dǎo)致 Cookie 格式錯(cuò)誤,無(wú)法存儲(chǔ)。
反正不是明確的告訴開(kāi)發(fā)者長(zhǎng)度異常了?。∷栽谑褂?nbsp;cookieStore
時(shí),需要進(jìn)行異常捕獲。
本文編寫(xiě)時(shí) Firefox 最新版本 138.0.4 還不支持 cookieStore。
Cookie 個(gè)數(shù)限制
單個(gè) Cookie 的大小限制了解了,再看看 Cookie 個(gè)數(shù)限制。
多個(gè)超大 Cookie
測(cè)試代碼:
(async () => {
document.cookie = ''
const name = 'name'
let cookieStr = ''
for (let i = 0; i < 200; i++) {
document.cookie = `${name + i}=${'a'.repeat(4000)};expires=${new Date(2026, 0, 1).toUTCString()};path=/`;
}
console.log(document.cookie.match(/name/g).length)
})()
第一次都能正常打開(kāi)頁(yè)面,第二次刷新頁(yè)面之后都會(huì)報(bào)錯(cuò):

此問(wèn)題應(yīng)該是跟 http 協(xié)議的限制有關(guān),請(qǐng)求頭發(fā)送的 Cookie 長(zhǎng)度太長(zhǎng)了,導(dǎo)致響應(yīng) 431 狀態(tài)碼。
Firefox 在頁(yè)面未正常打卡的情況下還不支持清空 Cookie,需要點(diǎn)擊右上角菜單--設(shè)置--隱私與安全--清除數(shù)據(jù)刪除保存的超大 Cookie 瀏覽器才能正常訪問(wèn)。
小 Cookie 個(gè)數(shù)限制
測(cè)試代碼:
(async () => {
function setCookie(name, value) {
return new Promise((resolve, reject) => {
setTimeout(() => {
document.cookie = `${name}=${value};path=/`;
resolve()
}, 5);
});
}
const name = 'name'
let cookieStr = ''
for (let i = 0; i < 2000; i++) {
console.log('正在寫(xiě)入:', i);
await setCookie(name + i, 'a')
}
setTimeout(() => {
console.log(document.cookie?.match(/name/g)?.length)
}, 1000);
})()
Chrome、Edge、Firefox 瀏覽器每次刷新寫(xiě)入的 Cookie 個(gè)數(shù)都不一樣,可以復(fù)制以上代碼在瀏覽器中測(cè)試!
AI 回答:

轉(zhuǎn)自https://www.cnblogs.com/linx/p/19010392
該文章在 2025/8/1 9:36:31 編輯過(guò)