Javascript Cookie,document.cookie

2023-02-17 10:57 更新

Cookie 是直接存儲(chǔ)在瀏覽器中的一小串?dāng)?shù)據(jù)。它們是 HTTP 協(xié)議的一部分,由 RFC 6265 規(guī)范定義。

Cookie 通常是由 Web 服務(wù)器使用響應(yīng) Set-Cookie HTTP-header 設(shè)置的。然后瀏覽器使用 Cookie HTTP-header 將它們自動(dòng)添加到(幾乎)每個(gè)對(duì)相同域的請(qǐng)求中。

最常見(jiàn)的用處之一就是身份驗(yàn)證:

  1. 登錄后,服務(wù)器在響應(yīng)中使用 ?Set-Cookie? HTTP-header 來(lái)設(shè)置具有唯一“會(huì)話標(biāo)識(shí)符(session identifier)”的 cookie。
  2. 下次當(dāng)請(qǐng)求被發(fā)送到同一個(gè)域時(shí),瀏覽器會(huì)使用 ?Cookie? HTTP-header 通過(guò)網(wǎng)絡(luò)發(fā)送 cookie。
  3. 所以服務(wù)器知道是誰(shuí)發(fā)起了請(qǐng)求。

我們還可以使用 document.cookie 屬性從瀏覽器訪問(wèn) cookie。

關(guān)于 cookie 及其選項(xiàng),有很多棘手的事情。在本章中,我們將詳細(xì)介紹它們。

從 document.cookie 中讀取

你的瀏覽器是否存儲(chǔ)了本網(wǎng)站的任何 cookie?讓我們來(lái)看看:

// 在 javascript.info,我們使用谷歌分析來(lái)進(jìn)行統(tǒng)計(jì),
// 所以應(yīng)該存在一些 cookie
alert( document.cookie ); // cookie1=value1; cookie2=value2;...

document.cookie 的值由 name=value 對(duì)組成,以 ; 分隔。每一個(gè)都是獨(dú)立的 cookie。

為了找到一個(gè)特定的 cookie,我們可以以 ; 作為分隔,將 document.cookie 分開(kāi),然后找到對(duì)應(yīng)的名字。我們可以使用正則表達(dá)式或者數(shù)組函數(shù)來(lái)實(shí)現(xiàn)。

我們把這個(gè)留給讀者當(dāng)作練習(xí)。此外,在本章的最后,你可以找到一些操作 cookie 的輔助函數(shù)。

寫(xiě)入 document.cookie

我們可以寫(xiě)入 document.cookie。但這不是一個(gè)數(shù)據(jù)屬性,它是一個(gè) 訪問(wèn)器(getter/setter)。對(duì)其的賦值操作會(huì)被特殊處理。

對(duì) document.cookie 的寫(xiě)入操作只會(huì)更新其中提到的 cookie,而不會(huì)涉及其他 cookie。

例如,此調(diào)用設(shè)置了一個(gè)名稱為 user 且值為 John 的 cookie:

document.cookie = "user=John"; // 只會(huì)更新名稱為 user 的 cookie
alert(document.cookie); // 展示所有 cookie

如果你運(yùn)行了上面這段代碼,你會(huì)看到多個(gè) cookie。這是因?yàn)?nbsp;document.cookie= 操作不是重寫(xiě)整所有 cookie。它只設(shè)置代碼中提到的 cookie user。

從技術(shù)上講,cookie 的名稱和值可以是任何字符。為了保持有效的格式,它們應(yīng)該使用內(nèi)建的 encodeURIComponent 函數(shù)對(duì)其進(jìn)行轉(zhuǎn)義:

// 特殊字符(空格),需要編碼
let name = "my name";
let value = "John Smith"

// 將 cookie 編碼為 my%20name=John%20Smith
document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);

alert(document.cookie); // ...; my%20name=John%20Smith

限制

存在一些限制:

  • ?encodeURIComponent? 編碼后的 ?name=value? 對(duì),大小不能超過(guò) 4KB。因此,我們不能在一個(gè) cookie 中保存大的東西。
  • 每個(gè)域的 cookie 總數(shù)不得超過(guò) 20+ 左右,具體限制取決于瀏覽器。

Cookie 有幾個(gè)選項(xiàng),其中很多都很重要,應(yīng)該設(shè)置它。

選項(xiàng)被列在 key=value 之后,以 ; 分隔,像這樣:

document.cookie = "user=John; path=/; expires=Tue, 19 Jan 2038 03:14:07 GMT"

path

  • ?path=/mypath?

url 路徑前綴必須是絕對(duì)路徑。它使得該路徑下的頁(yè)面可以訪問(wèn)該 cookie。默認(rèn)為當(dāng)前路徑。

如果一個(gè) cookie 帶有 path=/admin 設(shè)置,那么該 cookie 在 /admin 和 /admin/something 下都是可見(jiàn)的,但是在 /home 或 /adminpage 下不可見(jiàn)。

通常,我們應(yīng)該將 path 設(shè)置為根目錄:path=/,以使 cookie 對(duì)此網(wǎng)站的所有頁(yè)面可見(jiàn)。

domain

  • ?domain=site.com?

domain 控制了可訪問(wèn) cookie 的域。但是在實(shí)際中,有一些限制。我們無(wú)法設(shè)置任何域。

無(wú)法從另一個(gè)二級(jí)域訪問(wèn) cookie,因此 other.com 永遠(yuǎn)不會(huì)收到在 site.com 設(shè)置的 cookie。

這是一項(xiàng)安全限制,為了允許我們將敏感數(shù)據(jù)存儲(chǔ)在應(yīng)該僅在一個(gè)站點(diǎn)上可用的 cookie 中。

默認(rèn)情況下,cookie 只有在設(shè)置的域下才能被訪問(wèn)到。

請(qǐng)注意,默認(rèn)情況下,cookie 也不會(huì)共享給子域,例如 ?forum.site.com?。

// 如果我們?cè)?site.com 網(wǎng)站上設(shè)置了 cookie……
document.cookie = "user=John"

// ……在 forum.site.com 域下我們無(wú)法訪問(wèn)它
alert(document.cookie); // 沒(méi)有 user

……但這是可以設(shè)置的。如果我們想允許像 forum.site.com 這樣的子域在 site.com 上設(shè)置 cookie,也是可以實(shí)現(xiàn)的。

為此,當(dāng)在 site.com 設(shè)置 cookie 時(shí),我們應(yīng)該明確地將 domain 選項(xiàng)設(shè)置為根域:domain=site.com。那么,所有子域都可以訪問(wèn)到這樣的 cookie。

例如:

// 在 site.com
// 使 cookie 可以被在任何子域 *.site.com 訪問(wèn):
document.cookie = "user=John; domain=site.com"

// 之后

// 在 forum.site.com
alert(document.cookie); // 有 cookie user=John

出于歷史原因,domain=.site.comsite.com 前面有一個(gè)點(diǎn)符號(hào))也以相同的方式工作,允許從子域訪問(wèn) cookie。這是一個(gè)舊的表示方式,如果我們需要支持非常舊的瀏覽器,那么應(yīng)該使用它。

總結(jié)一下,通過(guò) domain 選項(xiàng)的設(shè)置,可以實(shí)現(xiàn)允許在子域訪問(wèn) cookie。

expires,max-age

默認(rèn)情況下,如果一個(gè) cookie 沒(méi)有設(shè)置這兩個(gè)參數(shù)中的任何一個(gè),那么在關(guān)閉瀏覽器之后,它就會(huì)消失。此類 cookie 被稱為 "session cookie”。

為了讓 cookie 在瀏覽器關(guān)閉后仍然存在,我們可以設(shè)置 expires 或 max-age 選項(xiàng)中的一個(gè)。

  • ?expires=Tue, 19 Jan 2038 03:14:07 GMT?

cookie 的過(guò)期時(shí)間定義了瀏覽器會(huì)自動(dòng)清除該 cookie 的時(shí)間。

日期必須完全采用 GMT 時(shí)區(qū)的這種格式。我們可以使用 date.toUTCString 來(lái)獲取它。例如,我們可以將 cookie 設(shè)置為 1 天后過(guò)期。

// 當(dāng)前時(shí)間 +1 天
let date = new Date(Date.now() + 86400e3);
date = date.toUTCString();
document.cookie = "user=John; expires=" + date;

如果我們將 expires 設(shè)置為過(guò)去的時(shí)間,則 cookie 會(huì)被刪除。

  • ?max-age=3600?

它是 expires 的替代選項(xiàng),指明了 cookie 的過(guò)期時(shí)間距離當(dāng)前時(shí)間的秒數(shù)。

如果將其設(shè)置為 0 或負(fù)數(shù),則 cookie 會(huì)被刪除:

// cookie 會(huì)在一小時(shí)后失效
document.cookie = "user=John; max-age=3600";

// 刪除 cookie(讓它立即過(guò)期)
document.cookie = "user=John; max-age=0";

secure

  • ?secure?

Cookie 應(yīng)只能被通過(guò) HTTPS 傳輸。

默認(rèn)情況下,如果我們?cè)?nbsp;http://site.com 上設(shè)置了 cookie,那么該 cookie 也會(huì)出現(xiàn)在 https://site.com 上,反之亦然。

也就是說(shuō),cookie 是基于域的,它們不區(qū)分協(xié)議。

使用此選項(xiàng),如果一個(gè) cookie 是通過(guò) https://site.com 設(shè)置的,那么它不會(huì)在相同域的 HTTP 環(huán)境下出現(xiàn),例如 http://site.com。所以,如果一個(gè) cookie 包含絕不應(yīng)該通過(guò)未加密的 HTTP 協(xié)議發(fā)送的敏感內(nèi)容,那么就應(yīng)該設(shè)置 secure 標(biāo)識(shí)。

// 假設(shè)我們現(xiàn)在在 HTTPS 環(huán)境下
// 設(shè)置 cookie secure(只在 HTTPS 環(huán)境下可訪問(wèn))
document.cookie = "user=John; secure";

samesite

這是另外一個(gè)關(guān)于安全的特性。它旨在防止 XSRF(跨網(wǎng)站請(qǐng)求偽造)攻擊。

為了了解它是如何工作的,以及何時(shí)有用,讓我們看一下 XSRF 攻擊。

XSRF 攻擊

想象一下,你登錄了 bank.com 網(wǎng)站。此時(shí):你有了來(lái)自該網(wǎng)站的身份驗(yàn)證 cookie。你的瀏覽器會(huì)在每次請(qǐng)求時(shí)將其發(fā)送到 bank.com,以便識(shí)別你,并執(zhí)行所有敏感的財(cái)務(wù)上的操作。

現(xiàn)在,在另外一個(gè)窗口中瀏覽網(wǎng)頁(yè)時(shí),你不小心訪問(wèn)了另一個(gè)網(wǎng)站 evil.com。該網(wǎng)站具有向 bank.com 網(wǎng)站提交一個(gè)具有啟動(dòng)與黑客賬戶交易的字段的表單 <form action="https://bank.com/pay"> 的 JavaScript 代碼。

你每次訪問(wèn) bank.com 時(shí),瀏覽器都會(huì)發(fā)送 cookie,即使該表單是從 evil.com 提交過(guò)來(lái)的。因此,銀行會(huì)識(shí)別你的身份,并執(zhí)行真實(shí)的付款。


這就是所謂的“跨網(wǎng)站請(qǐng)求偽造(Cross-Site Request Forgery,簡(jiǎn)稱 XSRF)”攻擊。

當(dāng)然,實(shí)際的銀行會(huì)防止出現(xiàn)這種情況。所有由 bank.com 生成的表單都具有一個(gè)特殊的字段,即所謂的 “XSRF 保護(hù) token”,惡意頁(yè)面既不能生成,也不能從遠(yuǎn)程頁(yè)面提取它。它可以在那里提交表單,但是無(wú)法獲取數(shù)據(jù)。并且,網(wǎng)站 bank.com 會(huì)對(duì)收到的每個(gè)表單都進(jìn)行這種 token 的檢查。

但是,實(shí)現(xiàn)這種防護(hù)需要花費(fèi)時(shí)間。我們需要確保每個(gè)表單都具有所需的 token 字段,并且我們還必須檢查所有請(qǐng)求。

輸入 cookie samesite 選項(xiàng)

Cookie 的 samesite 選項(xiàng)提供了另一種防止此類攻擊的方式,(理論上)不需要要求 “XSRF 保護(hù) token”。

它有兩個(gè)可能的值:

  • ?samesite=strict?(和沒(méi)有值的 ?samesite? 一樣)

如果用戶來(lái)自同一網(wǎng)站之外,那么設(shè)置了 samesite=strict 的 cookie 永遠(yuǎn)不會(huì)被發(fā)送。

換句話說(shuō),無(wú)論用戶是通過(guò)郵件鏈接還是從 evil.com 提交表單,或者進(jìn)行了任何來(lái)自其他域下的操作,cookie 都不會(huì)被發(fā)送。

如果身份驗(yàn)證 cookie 具有 samesite 選項(xiàng),那么 XSRF 攻擊是沒(méi)有機(jī)會(huì)成功的,因?yàn)閬?lái)自 evil.com 的提交沒(méi)有 cookie。因此,bank.com 將無(wú)法識(shí)別用戶,也就不會(huì)繼續(xù)進(jìn)行付款。

這種保護(hù)是相當(dāng)可靠的。只有來(lái)自 bank.com 的操作才會(huì)發(fā)送 samesite cookie,例如來(lái)自 bank.com 的另一頁(yè)面的表單提交。

雖然,這樣有一些不方便。

當(dāng)用戶通過(guò)合法的鏈接訪問(wèn) bank.com 時(shí),例如從他們自己的筆記,他們會(huì)感到驚訝,bank.com 無(wú)法識(shí)別他們的身份。實(shí)際上,在這種情況下不會(huì)發(fā)送 samesite=strict cookie。

我們可以通過(guò)使用兩個(gè) cookie 來(lái)解決這個(gè)問(wèn)題:一個(gè) cookie 用于“一般識(shí)別”,僅用于說(shuō) “Hello, John”,另一個(gè)帶有 samesite=strict 的 cookie 用于進(jìn)行數(shù)據(jù)更改的操作。這樣,從網(wǎng)站外部來(lái)的用戶會(huì)看到歡迎信息,但是支付操作必須是從銀行網(wǎng)站啟動(dòng)的,這樣第二個(gè) cookie 才能被發(fā)送。

  • ?samesite=lax?

一種更輕松的方法,該方法還可以防止 XSRF 攻擊,并且不會(huì)破壞用戶體驗(yàn)。

寬松(lax)模式,和 strict 模式類似,當(dāng)從外部來(lái)到網(wǎng)站,則禁止瀏覽器發(fā)送 cookie,但是增加了一個(gè)例外。

如果以下兩個(gè)條件均成立,則會(huì)發(fā)送含 samesite=lax 的 cookie:

  1. HTTP 方法是“安全的”(例如 GET 方法,而不是 POST)。
  2. 所有安全的 HTTP 方法詳見(jiàn) RFC7231 規(guī)范?;旧希@些都是用于讀取而不是寫(xiě)入數(shù)據(jù)的方法。它們不得執(zhí)行任何更改數(shù)據(jù)的操作。跟隨鏈接始終是 GET,是安全的方法。

  3. 該操作執(zhí)行頂級(jí)導(dǎo)航(更改瀏覽器地址欄中的 URL)。
  4. 這通常是成立的,但是如果導(dǎo)航是在一個(gè) <iframe> 中執(zhí)行的,那么它就不是頂級(jí)的。此外,用于網(wǎng)絡(luò)請(qǐng)求的 JavaScript 方法不會(huì)執(zhí)行任何導(dǎo)航,因此它們不適合。

所以,samesite=lax 所做的是基本上允許最常見(jiàn)的“前往 URL”操作攜帶 cookie。例如,從筆記中打開(kāi)網(wǎng)站鏈接就滿足這些條件。

但是,任何更復(fù)雜的事兒,例如來(lái)自另一個(gè)網(wǎng)站的網(wǎng)絡(luò)請(qǐng)求或表單提交都會(huì)丟失 cookie。

如果這種情況適合你,那么添加 samesite=lax 將不會(huì)破壞用戶體驗(yàn)并且可以增加保護(hù)。

總體而言,samesite 是一個(gè)很好的選項(xiàng)。

但它有個(gè)缺點(diǎn):

  • ?samesite? 會(huì)被到 2017 年左右的舊版本瀏覽器忽略(不兼容)。

因此,如果我們僅依靠 samesite 提供保護(hù),那么在舊版本的瀏覽器上將很容易受到攻擊。

但是,我們肯定可以將 samesite 與其他保護(hù)措施一起使用,例如 XSRF token,這樣可以多增加一層保護(hù),將來(lái),當(dāng)舊版本的瀏覽器淘汰時(shí),我們可能就可以刪除 xsrf token 這種方式了。

httpOnly

這個(gè)選項(xiàng)和 JavaScript 沒(méi)有關(guān)系,但是我們必須為了完整性也提一下它。

Web 服務(wù)器使用 Set-Cookie header 來(lái)設(shè)置 cookie。并且,它可以設(shè)置 httpOnly 選項(xiàng)。

這個(gè)選項(xiàng)禁止任何 JavaScript 訪問(wèn) cookie。我們使用 document.cookie 看不到此類 cookie,也無(wú)法對(duì)此類 cookie 進(jìn)行操作。

這是一種預(yù)防措施,當(dāng)黑客將自己的 JavaScript 代碼注入網(wǎng)頁(yè),并等待用戶訪問(wèn)該頁(yè)面時(shí)發(fā)起攻擊,而這個(gè)選項(xiàng)可以防止此時(shí)的這種攻擊。這應(yīng)該是不可能發(fā)生的,黑客應(yīng)該無(wú)法將他們的代碼注入我們的網(wǎng)站,但是網(wǎng)站有可能存在 bug,使得黑客能夠?qū)崿F(xiàn)這樣的操作。

通常來(lái)說(shuō),如果發(fā)生了這種情況,并且用戶訪問(wèn)了帶有黑客 JavaScript 代碼的頁(yè)面,黑客代碼將執(zhí)行并通過(guò) document.cookie 獲取到包含用戶身份驗(yàn)證信息的 cookie。這就很糟糕了。

但是,如果 cookie 設(shè)置了 httpOnly,那么 document.cookie 則看不到 cookie,所以它受到了保護(hù)。

附錄: Cookie 函數(shù)

這里有一組有關(guān) cookie 操作的函數(shù),比手動(dòng)修改 document.cookie 方便得多。

有很多這種 cookie 庫(kù),所以這些函數(shù)只用于演示。雖然它們都能正常使用。

getCookie(name)

獲取 cookie 最簡(jiǎn)短的方式是使用 正則表達(dá)式。

getCookie(name) 函數(shù)返回具有給定 name 的 cookie:

// 返回具有給定 name 的 cookie,
// 如果沒(méi)找到,則返回 undefined
function getCookie(name) {
  let matches = document.cookie.match(new RegExp(
    "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
  ));
  return matches ? decodeURIComponent(matches[1]) : undefined;
}

這里的 new RegExp 是動(dòng)態(tài)生成的,以匹配 ; name=<value>。

請(qǐng)注意 cookie 的值是經(jīng)過(guò)編碼的,所以 getCookie 使用了內(nèi)建方法 decodeURIComponent 函數(shù)對(duì)其進(jìn)行解碼。

setCookie(name, value, options)

將 cookie 的 name 設(shè)置為具有默認(rèn)值 path=/(可以修改以添加其他默認(rèn)值)和給定值 value

function setCookie(name, value, options = {}) {

  options = {
    path: '/',
    // 如果需要,可以在這里添加其他默認(rèn)值
    ...options
  };

  if (options.expires instanceof Date) {
    options.expires = options.expires.toUTCString();
  }

  let updatedCookie = encodeURIComponent(name) + "=" + encodeURIComponent(value);

  for (let optionKey in options) {
    updatedCookie += "; " + optionKey;
    let optionValue = options[optionKey];
    if (optionValue !== true) {
      updatedCookie += "=" + optionValue;
    }
  }

  document.cookie = updatedCookie;
}

// 使用范例:
setCookie('user', 'John', {secure: true, 'max-age': 3600});

deleteCookie(name)

要?jiǎng)h除一個(gè) cookie,我們可以給它設(shè)置一個(gè)負(fù)的過(guò)期時(shí)間來(lái)調(diào)用它:

function deleteCookie(name) {
  setCookie(name, "", {
    'max-age': -1
  })
}

更新或刪除必須使用相同的路徑和域

請(qǐng)注意:當(dāng)我們更新或刪除一個(gè) cookie 時(shí),我們應(yīng)該使用和設(shè)置 cookie 時(shí)相同的路徑和域選項(xiàng)。

代碼放在:cookie.js。

附錄:第三方 cookie

如果 cookie 是由用戶所訪問(wèn)的頁(yè)面的域以外的域放置的,則稱其為第三方 cookie。

例如:

  1. ?site.com? 網(wǎng)站的一個(gè)頁(yè)面加載了另外一個(gè)網(wǎng)站的 banner:?<img src="https://ads.com/banner.png" rel="external nofollow" >?。
  2. 與 banner 一起,?ads.com? 的遠(yuǎn)程服務(wù)器可能會(huì)設(shè)置帶有 ?id=1234? 這樣的 cookie 的 ?Set-Cookie? header。此類 cookie 源自 ?ads.com? 域,并且僅在 ?ads.com? 中可見(jiàn):

  3. 下次訪問(wèn) ads.com 網(wǎng)站時(shí),遠(yuǎn)程服務(wù)器獲取 cookie id 并識(shí)別用戶:

  4. 更為重要的是,當(dāng)用戶從 site.com 網(wǎng)站跳轉(zhuǎn)至另一個(gè)也帶有 banner 的網(wǎng)站 other.com 時(shí),ads.com 會(huì)獲得該 cookie,因?yàn)樗鼘儆?nbsp;ads.com,從而識(shí)別用戶并在他在網(wǎng)站之間切換時(shí)對(duì)其進(jìn)行跟蹤:

由于它的性質(zhì),第三方 cookie 通常用于跟蹤和廣告服務(wù)。它們被綁定在原始域上,因此 ads.com 可以在不同網(wǎng)站之間跟蹤同一用戶,如果這些網(wǎng)站都可以訪問(wèn) ads.com 的話。

當(dāng)然,有些人不喜歡被跟蹤,因此瀏覽器允許禁止此類 cookie。

此外,一些現(xiàn)代瀏覽器對(duì)此類 cookie 采取特殊策略:

  • Safari 瀏覽器完全不允許第三方 cookie。
  • Firefox 瀏覽器附帶了一個(gè)第三方域的黑名單,它阻止了來(lái)自名單內(nèi)的域的第三方 cookie。

請(qǐng)注意:

如果我們加載了一個(gè)來(lái)自第三方域的腳本,例如 <script src="https://google-analytics.com/analytics.js" rel="external nofollow" >,并且該腳本使用 document.cookie 設(shè)置了 cookie,那么此類 cookie 就不是第三方的。

如果一個(gè)腳本設(shè)置了一個(gè) cookie,那么無(wú)論腳本來(lái)自何處 —— 這個(gè) cookie 都屬于當(dāng)前網(wǎng)頁(yè)的域。

附錄: GDPR

本主題和 JavaScript 無(wú)關(guān),只是設(shè)置 cookie 時(shí)的一些注意事項(xiàng)。

歐洲有一項(xiàng)名為 GDPR 的立法,該法規(guī)針對(duì)網(wǎng)站尊重用戶實(shí)施了一系列規(guī)則。其中之一就是需要明確的許可才可以跟蹤用戶的 cookie。

請(qǐng)注意,這僅與跟蹤/識(shí)別/授權(quán) cookie 有關(guān)。

所以,如果我們?cè)O(shè)置一個(gè)只保存了一些信息的 cookie,但是既不跟蹤也不識(shí)別用戶,那么我們可以自由地設(shè)置它。

但是,如果我們要設(shè)置帶有身份驗(yàn)證會(huì)話(session)或跟蹤 id 的 cookie,那么必須得到用戶的允許。

網(wǎng)站為了遵循 GDPR 通常有兩種做法。你一定已經(jīng)在網(wǎng)站中看到過(guò)它們了:

  1. 如果一個(gè)網(wǎng)站想要僅為已經(jīng)經(jīng)過(guò)身份驗(yàn)證的用戶設(shè)置跟蹤的 cookie。
  2. 為此,注冊(cè)表單中必須要有一個(gè)復(fù)選框,例如“接受隱私政策”(描述怎么使用 cookie),用戶必須勾選它,然后網(wǎng)站就可以自由設(shè)置身份驗(yàn)證 cookie 了。

  3. 如果一個(gè)網(wǎng)站想要為所有人設(shè)置跟蹤的 cookie。
  4. 為了合法地這樣做,網(wǎng)站為每個(gè)新用戶顯示一個(gè)“初始屏幕”彈窗,并要求他們同意設(shè)置 cookie。之后網(wǎng)站就可以設(shè)置 cookie,并可以讓用戶看到網(wǎng)站內(nèi)容了。不過(guò),這可能會(huì)使新用戶感到反感。沒(méi)有人喜歡看到“必須點(diǎn)擊”的初始屏幕彈窗而不是網(wǎng)站內(nèi)容。但是 GDPR 要求必須得到用戶明確地準(zhǔn)許。

GDPR 不僅涉及 cookie,還涉及其他與隱私相關(guān)的問(wèn)題,但這超出了我們的討論范圍。

總結(jié)

document.cookie 提供了對(duì) cookie 的訪問(wèn)

  • 寫(xiě)入操作只會(huì)修改其中提到的 cookie。
  • name/value 必須被編碼。
  • 一個(gè) cookie 最大不能超過(guò) 4KB。每個(gè)域下最多允許有 20+ 個(gè)左右的 cookie(具體取決于瀏覽器)。

Cookie 選項(xiàng):

  • ?path=/?,默認(rèn)為當(dāng)前路徑,使 cookie 僅在該路徑下可見(jiàn)。
  • ?domain=site.com?,默認(rèn) cookie 僅在當(dāng)前域下可見(jiàn)。如果顯式地設(shè)置了域,可以使 cookie 在子域下也可見(jiàn)。
  • ?expires? 或 ?max-age? 設(shè)定了 cookie 過(guò)期時(shí)間。如果沒(méi)有設(shè)置,則當(dāng)瀏覽器關(guān)閉時(shí) cookie 就會(huì)失效。
  • ?secure? 使 cookie 僅在 HTTPS 下有效。
  • ?samesite?,如果請(qǐng)求來(lái)自外部網(wǎng)站,禁止瀏覽器發(fā)送 cookie。這有助于防止 XSRF 攻擊。

另外:

  • 瀏覽器可能會(huì)禁用第三方 cookie,例如 Safari 瀏覽器默認(rèn)禁止所有第三方 cookie。
  • 在為歐盟公民設(shè)置跟蹤 cookie 時(shí),GDPR 要求必須得到用戶明確許可。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)