在瀏覽器端,雖然以LocalStorage爲表明的本地持久化方案已經很是成熟,但cookie因其可跨三級及以上域名、可後端參與操做等特性,在涉及用戶驗證等諸多業務中依然被普遍運用。html
Cookie的基本組成主要由4部分組成:前端
咱們能夠用谷歌控制檯體會一下。web
打開suning.com
,而後在控制檯輸入如下代碼:小程序
document.cookie = `my_data=123; expires=${new Date(2021,0,1).toGMTString()};`
複製代碼
而後進入Application
->Cookie
->https://www.suning.com
,能夠看到my_data
已經被寫入列表。後端
在上面的例子中,咱們並無指定Path
和Domain
兩個值,因此瀏覽器給出了默認值:跨域
Path=/
做用於根及如下分支目錄Domain=www.suning.com
做用於該域若是但願Cookie在三級及以上域名做用,可簡單加一條:瀏覽器
document.cookie = `my_data=123; domain=suning.com; expires=${new Date(2021,0,1).toGMTString()};`
複製代碼
能夠看到,Cookie中增長了一條my_data
記錄domain=.suning.com
。這裏的.suning.com
能夠理解爲*.suning.com
。安全
關於Path
項及其餘Cookie項,這裏就很少作解釋了,你們能夠自行嘗試或者查詢資料,在控制檯裏盡情虐待瀏覽器的cookie。bash
這裏有幾個小的經驗追加一下:服務器
document.cookie
雖然是以字符串形式賦值與取值,但其背後的管理機制倒是相似Map類型。domain
path
等須要對應。好比:document.cookie = `my_data=123; domain=suning.com; expires=${new Date(0).toGMTString()};`
複製代碼
後端往前端塞cookie是一種經常使用操做,方法是在響應頭中設置set-cookie
。瀏覽器會接收這個頭部,並原樣設置到本地cookie中。
Set-Cookie: <name>=<value>[; <name>=<value>]...
[; expires=<date>]
[; domain=<domain_name>]
[; path=<some_path>]
[; secure]
[; httponly]
複製代碼
這個格式看起來是否是與剛纔設置document.cookie一致?補充最後兩項說明:
secure
表示cookie只能被髮送到http服務器。httponly
表示cookie不能被客戶端腳本獲取到。關於HTTP響應頭,這裏提兩個注意事項:
set-cookie
的。以前我曾遇到這樣一個案例:後端工程師使用NodeJS+KOA作服務,對容許跨域的請求設置了頭部Access-Control-Allow-Origin: *
。當服務使用Docker部署後,運維的同窗對前置的Nginx
也配置了Access-Control-Allow-Origin
,因此前端拿到的響應頭中出現兩個Access-Control-Allow-Origin
。結果瀏覽器斷定此項頭配置無效,形成跨域請求失敗。固然,set-cookie
出現多個沒有問題,只是此種狀況須要作適配處理。在進行web訪問時,一個web地址(URL)由protocol+domain+path組成。
www.suning.com
/aaa/b/cc/d.html
醬嬸兒的 這樣就造成了對一個網絡資源的有效定位,也就是一個Locator
。而這個URL實際上在全網範圍也是一個惟一標識,因此也是一個URI。簡單點說,URL是URI的一種。URN我沒有遇到(意識到?)典型的場景,按RFC來說一樣是URI的一個子集。
這二者的區別在於對URI轉義的字符集不一樣。encodeURI
並不會對一個URI的分割標記作出轉移,好比://
啦#
啦()
啦?&=
...,等等。
對encodeURIComponent
望文生義的話,是對URI部分的轉義,意圖是被轉義的部分不影響URL的解析,那麼就必須將其中的URI定義的字符所有轉義。例子:
window.location.href = `https://auth.suning.com?redir=${encodeURIComponent('https://www.suning.com')}`;
// https://auth.suning.com?redir=https%3A%2F%2Fwww.suning.com
window.location.href = `${encodeURI('https://www.suning.com/prod.do?location=北京')}`;
// https://www.suning.com/prod.do?location=%E5%8C%97%E4%BA%AC
複製代碼
最終的目的,是在不破壞URI的前提下,完整傳遞參數。
咱們獲取cookie的途徑,不只是響應頭的set-cookie
。也許是localStorage數據,也許是一次API請求。
因爲HTTP規範中,頭中只容許使用ASCII字符,因此在向請求頭塞cookie的時候,須要對cookie來源的字符串作預處理。這時候,就用到了encodeURI
/encodeURIComponent
。因爲在GMT時間格式中存在URI的敏感字,也就是說,被encodeURI的忽略的字符集,小於header容許的字符集。因此一次性encode並不可取,需在cookie拼接完成後,作全量分析和處理。
如文章開頭所說,爲了兼容、複用一些老的登陸框架,每每須要用到cookie處理機制。因爲前端AJAX沒法處理302請求問題,也就沒法處理寫cookie跳轉的登陸行爲,因此你可能須要一個後端接口去代理一系列的後端set-cookie行爲。
假設中間咱們跳轉了兩個頁面,每一個頁面set-cookie一次,那麼在代理頁面返回的響應頭中,會至少包含2條set-cookie
頭部。出於安全考慮,XMLHttpRequest
並不能拿到頭部的set-cookie
,因此接下來,咱們用小程序中的request方法,來做爲進一步演示cookie處理問題的工具。
(依然未完)