瀏覽器 WebView cookie 詳解

一、什么是cookie

早期的web頁面面臨最大的問題之一就是如何維持狀態,即服務器無法知道兩個請求是否來自同一個瀏覽器。之前,最簡單的方法就是在請求的頁面中插入一個token,然后在下次請求時將這個token返回至服務器。或者將token放在URL的query字符串中來傳遞。這兩種方法都需要手動操作,極易出錯,且安全風險極大。
為了解決此類問題,cookie的概念被提出,并應用。cookie就是瀏覽器存儲的一小段文本文件,存儲于瀏覽器安裝目錄下的cookie文件夾。cookie是純文本格式,不包含任何可執行代碼。web頁面或者服務器告知瀏覽器按照一定規范來存儲這些信息,并在隨后的請求中將這些信息發送至服務器,web服務器可以使用這些信息來識別不同用戶。

二、cookie是如何工作的

當網頁要發起網絡請求時,瀏覽器會先檢查是否有對應domain的cookie,有則自動添加在request header中的cookie字段中。這些都是瀏覽器自動幫我們做的,而且每一次網絡請求瀏覽器都會自動幫我們做。
由于存儲在cookie中的數據,每次網絡請求都會被瀏覽器自動放在request header中,所以什么樣的數據適合存儲在cookie中很重要。cookie中適合存儲每個請求都要發送給服務端的數據,比如身份認證信息以及其他基礎信息,瀏覽器自動處理大大免去了重復添加的操作。cookie標準限值每個域名下的cookie大小最大為4KB,超出該限制的cookie會被截掉并且不會發送至服務器。每個域名下的cookie數量最多為20個,但是跟多瀏覽器廠商實現時支持大于20個。

三、cookie的格式

在Chrome瀏覽器開發者模式下的console中執行 document.cookie 即可獲得當前頁面domain下瀏覽器cookie,此方法只能獲取非HttpOnly類型的cookie。
cookie為一段字符串,由鍵值對 key=value構成,鍵值對之間由一個分號和一個空格隔開。

示例:"PSTM=1560166948; BD_UPN=123253; H_PS_PSSID=1459_21105_30211_30087_30071"

cookie的屬性選項

每個cookie都有屬性,標識其過期時間,發送的域名路徑,是否安全等。在設置cookie時都可以設置相關的屬性,不設置則使用這些屬性的默認值。在設置這些屬性時,屬性之間由一個分號和一個空格隔開。

如:"key=name; expires=2020-12-01T09:31:28.943Z; domain=.baidu.com; path=/; secure; HttpOnly"

1.expires / max-age

expires 選項用來設置cookie的過期時間,其格式必須是GMT格式的時間。對于失效的cookie瀏覽器會清空。如果沒有設置該選項,則默認有效期為session,即會話cookie,瀏覽器關閉時會將會話cookie清空。
新的http/1.1協議中expires已經由max-age替代,兩者不同點在于 expires為一個時間點,即cookie的失效時刻=expires,而max-age為一個以秒為單位的時間段,即cookie失效時間=創建時間+max-age。
max-age的默認值為-1,即session cookie。值為0時代表刪除cookie。大于0 的值時cookie失效時間=創建時間+max-age。

2.domain 和 path

domain和path 共同決定了cookie會被自動添加到哪個或者哪些接口的request header中,如果沒有設置這兩個選項,則會使用默認值。domain默認值為設置該cookie的網頁所在的域名,path默認值為設置該cookie的網頁所在的目錄。
例如:某cookie的domain為baidu.com,path為/,若請求的URL的域名為baidu.com或者其子域名,且URL的路徑為"/"或者子路徑,則瀏覽器會將此cookie添加到該請求的request header中。
該規則必須是同域的請求,即網絡請求域名和頁面域名必須是一樣的,發生跨域請求時,即使請求接口域名和路徑都滿足cookie的domain和path,默認情況下也不會自動添加到請求頭部中,詳細可參考文章:你真的會使用XMLHTTPRequest嗎 中關于跨域請求的部分。

3.secure

secure選項用來設置cookie只有在確保安全的請求中才會發送,例如https協議。
默認情況下,secure選項為空,即https與http協議都會將該cookie發送至服務端。在網頁中設置secure類型的cookie時必須保證網頁是https協議的,在http協議中無法設置secure類型的cookie。

4.HttpOnly

HttpOnly用來設置cookie能否通過js訪問,包括讀取、修改、刪除等。默認HttpOnly選項為空,網頁可以通過js訪問該cookie。HttpOnly類型的cookie只能通過服務端來設置和讀取。此類型的cookie比較安全,常用來做用戶信息的存儲。

5.SameSite

SameSite屬性用來限制第三方cookie,減少安全風險。其可以設置三個值

  • Strict
    Strict最為嚴格,完全禁止第三方cookie,在跨域時,任何情況下都不會發送cookie。只有當請求和當前網頁的URL域名一致時才會帶上cookie。
  • Lax

    Lax稍微寬松,但是大多數情況下 也不會發送第三方cookie。發送cookie的只有導航到目標地址的GET請求,詳見下表:
    image.png
  • None
    關閉SameSite屬性,設置SameSite = None的前提是必須設置Secure屬性。

四、如何設置cookie

cookie既可以由服務端來設置,也可以由前端來設置,但是HttpOnly的cookie只能由服務端設置。

1.服務端設置cookie

前端發送ajax請求,服務端都會返回response,response中有一項為set-cookie,是服務端用來設置cookie的。每次set只能設置一個cookie,在設置cookie內容的同時可以設置相關屬性選項。如果要設置多個cookie,需要添加多個Set-Cookie字段.服務端可以設置cookie的所有屬性:expires、domain、path、secure、HttpOnly、SameSite。

例如:
image.png
2.前端設置cookie

前端我們也可以通過執行document.cookie代碼設置cookie。一次只能設置一個cookie,若要設置多個,則需要多次執行document.cookie方法。前端只可以設置expires、domain、path,以及在https協議的網頁中設置secure。

代碼示例:
document.cookie="age=26; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/"
document.cookie="userid=oneuser; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/"
document.cookie="nickname=may; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=baidu.com; path=/"

五、其他補充

1.cookie編碼

cookie是一個字符串,且使用了逗號、分號、空格作為特殊字符,當cookie的key和value中包含了這個三個特殊字符時需要進行編碼,一般使用escape進行編碼,讀取時使用unescape進行解碼,也可以使用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI。

2.cookie何時會被覆蓋

當name、domain、path都相同時。

3.關于domain的說明
  • 如果未設置cookie.domain ,則瀏覽器自動取URL的host作為domain值。
  • value值前邊帶點和不帶點的區別,如:baidu.com 與 .baidu.com 。帶點的值表示任何的子域名都可以訪問;不帶點的值表示只有完全一樣的域名才能訪問,子域名不能訪問。

六、參考的一些資料

感謝以下文章的作者

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容