成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

聊一聊 cookie

entner / 964人閱讀

摘要:如我當(dāng)前打開的網(wǎng)址為,在控制臺(tái)中我們執(zhí)行了下面代碼查看瀏覽器面板如下圖所示,確實(shí)設(shè)置成功了,而且屬性選項(xiàng)都用了默認(rèn)值。

咱們不搞一開始就一大堆理論知識(shí)介紹,怕把人講懵了...... 咱們換一個(gè)思維方式——"從現(xiàn)象看本質(zhì)",先說說我們看到了什么,再從看到的現(xiàn)象中提出問題,最后深入尋找答案。

我們看到的 cookie

我自己創(chuàng)建了一個(gè)網(wǎng)站,網(wǎng)址為http://ppsc.sankuai.com。在這個(gè)網(wǎng)頁中我設(shè)置了幾個(gè)cookieJSSESSIONID,PA_VTIMEskmtutc,test。

在 chrome 瀏覽器中打開這個(gè)網(wǎng)站,進(jìn)入開發(fā)者模式,點(diǎn)擊Resources欄 -> 選擇cookies,我們會(huì)看到如下圖所示的界面:

解釋一下:左邊欄Cookies下方會(huì)列舉當(dāng)前網(wǎng)頁中設(shè)置過cookie的域都有哪些。上圖中只有一個(gè)域,即“ppsc.sankuai.com”。而右側(cè)區(qū)域顯示的就是某個(gè)域下具體的 cookie 列表,對(duì)應(yīng)上圖就是“ppsc.sankuai.com”域下設(shè)置的4個(gè)cookie。

在這個(gè)網(wǎng)頁中我往http://ppsc.sankuai.com/getList接口發(fā)了一個(gè) Ajax 請(qǐng)求,request header如下圖所示:

從上圖中我們會(huì)看到request header中自動(dòng)添加了Cookie字段(我并沒有手動(dòng)添加這個(gè)字段哦~),Cookie字段的值其實(shí)就是我設(shè)置的那4個(gè) cookie。這個(gè)請(qǐng)求最終會(huì)發(fā)送到http://ppsc.sankuai.com這個(gè)服務(wù)器上,這個(gè)服務(wù)器就能從接收到的request header中提取那4個(gè)cookie。

上面兩張圖展示了cookie的基本通信流程:設(shè)置cookie => cookie被自動(dòng)添加到request header中 => 服務(wù)端接收到cookie。這個(gè)流程中有幾個(gè)問題需要好好研究:

什么樣的數(shù)據(jù)適合放在cookie中?

cookie是怎么設(shè)置的?

cookie為什么會(huì)自動(dòng)加到request header中?

cookie怎么增刪查改?

我們要帶著這幾個(gè)問題繼續(xù)往下閱讀。

cookie 是怎么工作的?

首先必須明確一點(diǎn),存儲(chǔ)cookie是瀏覽器提供的功能。cookie 其實(shí)是存儲(chǔ)在瀏覽器中的純文本,瀏覽器的安裝目錄下會(huì)專門有一個(gè) cookie 文件夾來存放各個(gè)域下設(shè)置的cookie。

當(dāng)網(wǎng)頁要發(fā)http請(qǐng)求時(shí),瀏覽器會(huì)先檢查是否有相應(yīng)的cookie,有則自動(dòng)添加在request header中的cookie字段中。這些是瀏覽器自動(dòng)幫我們做的,而且每一次http請(qǐng)求瀏覽器都會(huì)自動(dòng)幫我們做。這個(gè)特點(diǎn)很重要,因?yàn)檫@關(guān)系到“什么樣的數(shù)據(jù)適合存儲(chǔ)在cookie中”。

存儲(chǔ)在cookie中的數(shù)據(jù),每次都會(huì)被瀏覽器自動(dòng)放在http請(qǐng)求中,如果這些數(shù)據(jù)并不是每個(gè)請(qǐng)求都需要發(fā)給服務(wù)端的數(shù)據(jù),瀏覽器這設(shè)置自動(dòng)處理無疑增加了網(wǎng)絡(luò)開銷;但如果這些數(shù)據(jù)是每個(gè)請(qǐng)求都需要發(fā)給服務(wù)端的數(shù)據(jù)(比如身份認(rèn)證信息),瀏覽器這設(shè)置自動(dòng)處理就大大免去了重復(fù)添加操作。所以對(duì)于那設(shè)置“每次請(qǐng)求都要攜帶的信息(最典型的就是身份認(rèn)證信息)”就特別適合放在cookie中,其他類型的數(shù)據(jù)就不適合了。

但在 localStorage 出現(xiàn)之前,cookie被濫用當(dāng)做了存儲(chǔ)工具。什么數(shù)據(jù)都放在cookie中,即使這些數(shù)據(jù)只在頁面中使用而不需要隨請(qǐng)求傳送到服務(wù)端。當(dāng)然cookie標(biāo)準(zhǔn)還是做了一些限制的:每個(gè)域名下的cookie 的大小最大為4KB,每個(gè)域名下的cookie數(shù)量最多為20個(gè)(但很多瀏覽器廠商在具體實(shí)現(xiàn)時(shí)支持大于20個(gè))。

cookie 的格式 document.cookie

JS 原生的 API提供了獲取cookie的方法:document.cookie(注意,這個(gè)方法只能獲取非 HttpOnly 類型的cookie)。在 console 中執(zhí)行這段代碼可以看到結(jié)果如下圖:

打印出的結(jié)果是一個(gè)字符串類型,因?yàn)?b>cookie本身就是存儲(chǔ)在瀏覽器中的字符串。但這個(gè)字符串是有格式的,由鍵值對(duì) key=value構(gòu)成,鍵值對(duì)之間由一個(gè)分號(hào)和一個(gè)空格隔開。

cookie 的屬性選項(xiàng)

每個(gè)cookie都有一定的屬性,如什么時(shí)候失效,要發(fā)送到哪個(gè)域名,哪個(gè)路徑等等。這些屬性是通過cookie選項(xiàng)來設(shè)置的,cookie選項(xiàng)包括:expires、domain、path、secure、HttpOnly。在設(shè)置任一個(gè)cookie時(shí)都可以設(shè)置相關(guān)的這些屬性,當(dāng)然也可以不設(shè)置,這時(shí)會(huì)使用這些屬性的默認(rèn)值。在設(shè)置這些屬性時(shí),屬性之間由一個(gè)分號(hào)和一個(gè)空格隔開。代碼示例如下:

"key=name; expires=Thu, 25 Feb 2016 04:18:00 GMT; domain=ppsc.sankuai.com; path=/; secure; HttpOnly"
expires

expires選項(xiàng)用來設(shè)置“cookie 什么時(shí)間內(nèi)有效”。expires其實(shí)是cookie失效日期,expires必須是 GMT 格式的時(shí)間(可以通過 new Date().toGMTString()或者 new Date().toUTCString() 來獲得)。

expires=Thu, 25 Feb 2016 04:18:00 GMT表示cookie講在2016年2月25日4:18分之后失效,對(duì)于失效的cookie瀏覽器會(huì)清空。如果沒有設(shè)置該選項(xiàng),則默認(rèn)有效期為session,即會(huì)話cookie。這種cookie在瀏覽器關(guān)閉后就沒有了。

expires 是 http/1.0協(xié)議中的選項(xiàng),在新的http/1.1協(xié)議中expires已經(jīng)由 max-age 選項(xiàng)代替,兩者的作用都是限制cookie 的有效時(shí)間。expires的值是一個(gè)時(shí)間點(diǎn)(cookie失效時(shí)刻= expires),而max-age 的值是一個(gè)以為單位時(shí)間段(cookie失效時(shí)刻= 創(chuàng)建時(shí)刻+ max-age)。
另外,max-age 的默認(rèn)值是 -1(即有效期為 session );若max-age有三種可能值:負(fù)數(shù)、0、正數(shù)。負(fù)數(shù):有效期session;0:刪除cookie;正數(shù):有效期為創(chuàng)建時(shí)刻+ max-age

domain 和 path

domain是域名,path是路徑,兩者加起來就構(gòu)成了 URL,domainpath一起來限制 cookie 能被哪些 URL 訪問。

一句話概括:某cookie的 domain為“baidu.com”, path為“/ ”,若請(qǐng)求的URL(URL 可以是js/html/img/css資源請(qǐng)求,但不包括 XHR 請(qǐng)求)的域名是“baidu.com”或其子域如“api.baidu.com”、“dev.api.baidu.com”,且 URL 的路徑是“/ ”或子路徑“/home”、“/home/login”,則瀏覽器會(huì)將此 cookie 添加到該請(qǐng)求的 cookie 頭部中。

所以domainpath2個(gè)選項(xiàng)共同決定了cookie何時(shí)被瀏覽器自動(dòng)添加到請(qǐng)求頭部中發(fā)送出去。如果沒有設(shè)置這兩個(gè)選項(xiàng),則會(huì)使用默認(rèn)值。domain的默認(rèn)值為設(shè)置該cookie的網(wǎng)頁所在的域名,path默認(rèn)值為設(shè)置該cookie的網(wǎng)頁所在的目錄。

特別說明1:
發(fā)生跨域xhr請(qǐng)求時(shí),即使請(qǐng)求URL的域名和路徑都滿足 cookie 的 domain 和 path,默認(rèn)情況下cookie也不會(huì)自動(dòng)被添加到請(qǐng)求頭部中。若想知道原因請(qǐng)閱讀本文最后一節(jié))

特別說明2:
domain是可以設(shè)置為頁面本身的域名(本域),或頁面本身域名的父域,但不能是公共后綴 public suffix。舉例說明下:如果頁面域名為 www.baidu.com, domain可以設(shè)置為“www.baidu.com”,也可以設(shè)置為“baidu.com”,但不能設(shè)置為“.com”或“com”。

secure

secure選項(xiàng)用來設(shè)置cookie只在確保安全的請(qǐng)求中才會(huì)發(fā)送。當(dāng)請(qǐng)求是HTTPS或者其他安全協(xié)議時(shí),包含 secure 選項(xiàng)的 cookie 才能被發(fā)送至服務(wù)器。

默認(rèn)情況下,cookie不會(huì)帶secure選項(xiàng)(即為空)。所以默認(rèn)情況下,不管是HTTPS協(xié)議還是HTTP協(xié)議的請(qǐng)求,cookie 都會(huì)被發(fā)送至服務(wù)端。但要注意一點(diǎn),secure選項(xiàng)只是限定了在安全情況下才可以傳輸給服務(wù)端,但并不代表你不能看到這個(gè) cookie。

下面我們?cè)O(shè)置一個(gè) secure類型的 cookie:

document.cookie = "name=huang; secure";

之后你就能在控制臺(tái)中看到這個(gè) cookie 了,如下圖所示:

這里有個(gè)坑需要注意下:
如果想在客戶端即網(wǎng)頁中通過 js 去設(shè)置secure類型的 cookie,必須保證網(wǎng)頁是https協(xié)議的。在http協(xié)議的網(wǎng)頁中是無法設(shè)置secure類型cookie的。

httpOnly

這個(gè)選項(xiàng)用來設(shè)置cookie是否能通過 js 去訪問。默認(rèn)情況下,cookie不會(huì)帶httpOnly選項(xiàng)(即為空),所以默認(rèn)情況下,客戶端是可以通過js代碼去訪問(包括讀取、修改、刪除等)這個(gè)cookie的。當(dāng)cookiehttpOnly選項(xiàng)時(shí),客戶端則無法通過js代碼去訪問(包括讀取、修改、刪除等)這個(gè)cookie。

在客戶端是不能通過js代碼去設(shè)置一個(gè)httpOnly類型的cookie的,這種類型的cookie只能通過服務(wù)端來設(shè)置。

那我們?cè)陧撁嬷性趺粗滥男?b>cookie是httpOnly類型的呢?看下圖:

凡是httpOnly類型的cookie,其 HTTP 一列都會(huì)打上√,如上圖中的PA_VTIME。你通過document.cookie是不能獲取的,也不能修改PA_VTIME的。

——httpOnly與安全

從上面介紹中,大家是否會(huì)有這樣的疑問:為什么我們要限制客戶端去訪問cookie?其實(shí)這樣做是為了保障安全。

試想:如果任何 cookie 都能被客戶端通過document.cookie獲取會(huì)發(fā)生什么可怕的事情。當(dāng)我們的網(wǎng)頁遭受了 XSS 攻擊,有一段惡意的script腳本插到了網(wǎng)頁中。這段script腳本做的事情是:通過document.cookie讀取了用戶身份驗(yàn)證相關(guān)的 cookie,并將這些 cookie 發(fā)送到了攻擊者的服務(wù)器。攻擊者輕而易舉就拿到了用戶身份驗(yàn)證信息,于是就可以搖搖大擺地冒充此用戶訪問你的服務(wù)器了(因?yàn)楣粽哂泻戏ǖ挠脩羯矸蒡?yàn)證信息,所以會(huì)通過你服務(wù)器的驗(yàn)證)。

如何設(shè)置 cookie?

知道了cookie的格式,cookie的屬性選項(xiàng),接下來我們就可以設(shè)置cookie了。首先得明確一點(diǎn):cookie既可以由服務(wù)端來設(shè)置,也可以由客戶端來設(shè)置。

服務(wù)端設(shè)置 cookie

不管你是請(qǐng)求一個(gè)資源文件(如 html/js/css/圖片),還是發(fā)送一個(gè)ajax請(qǐng)求,服務(wù)端都會(huì)返回response。而response header中有一項(xiàng)叫set-cookie,是服務(wù)端專門用來設(shè)置cookie的。如下圖所示,服務(wù)端返回的response header中有5個(gè)set-cookie字段,每個(gè)字段對(duì)應(yīng)一個(gè)cookie(注意不能將多個(gè)cookie放在一個(gè)set-cookie字段中),set-cookie字段的值就是普通的字符串,每個(gè)cookie還設(shè)置了相關(guān)屬性選項(xiàng)。

注意:

一個(gè)set-Cookie字段只能設(shè)置一個(gè)cookie,當(dāng)你要想設(shè)置多個(gè) cookie,需要添加同樣多的set-Cookie字段。

服務(wù)端可以設(shè)置cookie 的所有選項(xiàng):expiresdomain、pathsecure、HttpOnly

客戶端設(shè)置 cookie

在網(wǎng)頁即客戶端中我們也可以通過js代碼來設(shè)置cookie。如我當(dāng)前打開的網(wǎng)址為http://dxw.st.sankuai.com/mp/,在控制臺(tái)中我們執(zhí)行了下面代碼:

document.cookie = "name=Jonh; ";

查看瀏覽器 cookie 面板如下圖所示,cookie確實(shí)設(shè)置成功了,而且屬性選項(xiàng) domain、path、expires都用了默認(rèn)值。

再執(zhí)行下面代碼:

document.cookie="age=12; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/";

查看瀏覽器cookie 面板,如下圖所示,新的cookie設(shè)置成功了,而且屬性選項(xiàng) domain、path、expires都變成了設(shè)定的值。

注意:

客戶端可以設(shè)置cookie 的下列選項(xiàng):expires、domain、path、secure(有條件:只有在https協(xié)議的網(wǎng)頁中,客戶端設(shè)置secure類型的 cookie 才能成功),但無法設(shè)置HttpOnly選項(xiàng)。

用 js 如何設(shè)置多個(gè) cookie

當(dāng)要設(shè)置多個(gè)cookie時(shí), js 代碼很自然地我們會(huì)這么寫:

document.cookie = "name=Jonh; age=12; class=111";

但你會(huì)發(fā)現(xiàn)這樣寫只是添加了第一個(gè)cookie“name=John”,后面的所有cookie都沒有添加成功。所以最簡(jiǎn)單的設(shè)置多個(gè)cookie的方法就在重復(fù)執(zhí)行document.cookie = "key=name",如下:

document.cookie = "name=Jonh";
document.cookie = "age=12";
document.cookie = "class=111";
如何修改、刪除 修改 cookie

要想修改一個(gè)cookie,只需要重新賦值就行,舊的值會(huì)被新的值覆蓋。但要注意一點(diǎn),在設(shè)置新cookie時(shí),path/domain這幾個(gè)選項(xiàng)一定要舊cookie 保持一樣。否則不會(huì)修改舊值,而是添加了一個(gè)新的 cookie。

刪除 cookie

刪除一個(gè)cookie 也挺簡(jiǎn)單,也是重新賦值,只要將這個(gè)新cookie的expires 選項(xiàng)設(shè)置為一個(gè)過去的時(shí)間點(diǎn)就行了。但同樣要注意,path/domain/這幾個(gè)選項(xiàng)一定要舊cookie 保持一樣。

cookie 編碼

cookie其實(shí)是個(gè)字符串,但這個(gè)字符串中逗號(hào)、分號(hào)、空格被當(dāng)做了特殊符號(hào)。所以當(dāng)cookie的 key 和 value 中含有這3個(gè)特殊字符時(shí),需要對(duì)其進(jìn)行額外編碼,一般會(huì)用escape進(jìn)行編碼,讀取時(shí)用unescape進(jìn)行解碼;當(dāng)然也可以用encodeURIComponent/decodeURIComponent或者encodeURI/decodeURI(三者的區(qū)別可以參考這篇文章)。

var key = escape("name;value");
var value = escape("this is a value contain , and ;");
document.cookie= key + "=" + value + "; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/";
跨域請(qǐng)求中 cookie

之前在介紹 XHR 的一篇文章里面提過:默認(rèn)情況下,在發(fā)生跨域時(shí),cookie 作為一種 credential 信息是不會(huì)被傳送到服務(wù)端的。必須要進(jìn)行額外設(shè)置才可以。具體原因和如何設(shè)置可以參考我的這篇文章:你真的會(huì)使用XMLHttpRequest嗎?

另外,關(guān)于跨域資源共享 CORS極力推薦大家閱讀阮一峰老師的這篇 跨域資源共享 CORS 詳解。

其他補(bǔ)充

什么時(shí)候 cookie 會(huì)被覆蓋:name/domain/path 這3個(gè)字段都相同的時(shí)候;

關(guān)于domain的補(bǔ)充說明(參考1/參考2):

如果顯式設(shè)置了 domain,則設(shè)置成什么,瀏覽器就存成什么;但如果沒有顯式設(shè)置,則瀏覽器會(huì)自動(dòng)取 url 的 host 作為 domain 值;

新的規(guī)范中,顯式設(shè)置 domain 時(shí),如果 value 最前面帶點(diǎn),則瀏覽器處理時(shí)會(huì)將這個(gè)點(diǎn)去掉,所以最后瀏覽器存的就是沒有點(diǎn)的(注意:但目前大多數(shù)瀏覽器并未全部這么實(shí)現(xiàn))

前面帶點(diǎn)‘.’和不帶點(diǎn)‘.’有啥區(qū)別:

帶點(diǎn):任何 subdomain 都可以訪問,包括父 domain

不帶點(diǎn):只有完全一樣的域名才能訪問,subdomain 不能(但在 IE 下比較特殊,它支持 subdomain 訪問)

總結(jié)

咱們今天就聊到這里,若有不對(duì)之處歡迎各位指正~~
最后附上一些參考資料:

http://www.quirksmode.org/js/...

http://www.tutorialspoint.com...

http://www.allaboutcookies.or...

http://bubkoo.com/2014/04/21/...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86277.html

相關(guān)文章

  • [一聊系列]一聊前端存儲(chǔ)那些事兒

    摘要:如圖圖顧名思義,,是級(jí)別的存儲(chǔ)。如筆者寫的一篇淺析文章聊一聊百度移動(dòng)端首頁前端速度那些事兒讀者們可以嘗試使用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog/frontenddriver 在web開發(fā)越來越復(fù)雜的今天,前端擁有的能力也越來越多。其中最重要的一項(xiàng)莫過于web存儲(chǔ)。...

    caige 評(píng)論0 收藏0
  • [一聊系列]一聊WEB前端安全那些事兒

    摘要:所以今天,就和大家一起聊一聊前端的安全那些事兒。我們就聊一聊前端工程師們需要注意的那些安全知識(shí)。殊不知,這不僅僅是違反了的標(biāo)準(zhǔn)而已,也同樣會(huì)被黑客所利用。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog... 隨著互聯(lián)網(wǎng)的發(fā)達(dá),各種WEB應(yīng)用也變得越來越復(fù)雜,滿足了用戶的各種需求...

    AZmake 評(píng)論0 收藏0
  • [一聊系列]一聊百度移動(dòng)端首頁前端速度那些事兒

    摘要:要快,但是我們的服務(wù)也必須萬無一失,后續(xù)我會(huì)分享百度移動(dòng)端首頁的前端架構(gòu)設(shè)計(jì)那么這樣的優(yōu)化,是如何做到的呢,又如何兼顧穩(wěn)定性,架構(gòu)性,與速度呢別急,讓我們把這些優(yōu)化一一道來。百度移動(dòng)端首頁的很多就是這樣緩存在客戶端的。 歡迎大家收看聊一聊系列,這一套系列文章,可以幫助前端工程師們了解前端的方方面面(不僅僅是代碼):https://segmentfault.com/blog/fronte...

    The question 評(píng)論0 收藏0
  • 一聊web開發(fā)中的session和cookie

    摘要:瀏覽器主要保存服務(wù)端發(fā)送給用戶瀏覽器和頁面調(diào)用所設(shè)置的小片數(shù)據(jù)。瀏覽器在磁盤上保存并且在下一次請(qǐng)求時(shí)發(fā)送給相同的服務(wù)器。也稱為會(huì)話,包含和兩部分,客戶端通過記錄會(huì)話標(biāo)識(shí),服務(wù)端通過會(huì)話標(biāo)識(shí)找到對(duì)應(yīng)的。黑客可以通過注入和利用中的信息。 瀏覽器 cookie 主要保存服務(wù)端發(fā)送給用戶瀏覽器和頁面調(diào)用 document.cookie=? 所設(shè)置的小片數(shù)據(jù)。瀏覽器在磁盤上保存 cookie 并...

    gself 評(píng)論0 收藏0
  • 一聊Cookie(小甜餅),及其涉及到的web安全吧

    摘要:最近在用寫自己的博客,發(fā)現(xiàn)總是掉到的坑,于是就好好八一八這個(gè)小甜餅,沒想到居然還說很有意思的,每一個(gè)知識(shí)點(diǎn)都能拉出一條大魚,想想自己之前對(duì),簡(jiǎn)直就是它認(rèn)識(shí)我,我只能叫出他的名字。 最近在用thinkjs寫自己的博客,發(fā)現(xiàn)總是掉到cookie的坑,于是就好好八一八這個(gè)小甜餅,沒想到居然還說很有意思的,每一個(gè)知識(shí)點(diǎn)都能拉出一條大魚,想想自己之前對(duì)cookie,簡(jiǎn)直就是它認(rèn)識(shí)我,我只能叫出他...

    Donne 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<