Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
者:ConardLi 來(lái)源:code秘密花園
轉(zhuǎn)載地址:https://mp.weixin.qq.com/s/7aWSZtitdOuMrRaxMZoYVQ
ookie 為 Web 應(yīng)用程序保存用戶相關(guān)信息提供了一種有用的方法。例如,當(dāng)用戶訪問(wèn)咱們的站點(diǎn)時(shí),可以利用 Cookie 保存用戶首選項(xiàng)或其他信息,這樣,當(dāng)用戶下次再訪問(wèn)咱們的站點(diǎn)時(shí),應(yīng)用程序就可以檢索以前保存的信息。
Cookie 是一小段文本信息,伴隨著用戶請(qǐng)求和頁(yè)面在 Web 服務(wù)器和瀏覽器之間傳遞。用戶每次訪問(wèn)站點(diǎn)時(shí),Web 應(yīng)用程序都可以讀取 Cookie 包含的信息。
Cookie的出現(xiàn)是為了解決保存用戶信息的問(wèn)題。例如
Cookie 能在所有網(wǎng)頁(yè)中記住用戶的信息。它以字符串的形式包含信息,并鍵值對(duì)的形式保存的,即key=value的格式。各個(gè)cookie之間一般是以“;”分隔。
username=Daisy Green
服務(wù)器以cookie的形式向訪問(wèn)者的瀏覽器發(fā)送一些數(shù)據(jù)。如果瀏覽器允許接受 cookie。則將其作為純文本記錄存儲(chǔ)在訪問(wèn)者的硬盤上。
當(dāng)訪問(wèn)者跳轉(zhuǎn)到另一個(gè)頁(yè)面時(shí),瀏覽器會(huì)將相同的cookie發(fā)送到服務(wù)器進(jìn)行檢索。一旦檢索到它,您的服務(wù)器就知道或記得以前存儲(chǔ)了什么。
Cookie 在HTTP的頭部Header信息中,HTTP Set-Cookie的Header格式如下:
Set-Cookie: name=value; [expires=date]; [path=path]; [domain=domainname]; [secure];
在HTTP代碼中一個(gè)具體的例子:
<meta http-equiv="set-cookie" content=" cookieName=cookieValue; expires=01-Dec-2006 01:14:26 GMT; path=/" />
從上面的格式可以看出,Cookie由下面幾部分組成。
Name/Value對(duì)
Name/Value由分號(hào)分隔,一個(gè)Cookie最多有20對(duì),每個(gè)網(wǎng)頁(yè)最多有一個(gè)Cookie,Value的長(zhǎng)度不超過(guò)4K。對(duì)于Value值,最好用encodeURIComponent對(duì)其編碼。
Domain
Domain域名也是Cookie的一部分,默認(rèn)情況下,用戶訪問(wèn)網(wǎng)頁(yè)的域名會(huì)存放在Cookie中。如果設(shè)置了這個(gè)Cookie的域名值,那么意味著域名上的所有服務(wù)器,而不僅是你正在訪問(wèn)的服務(wù)器,都能訪問(wèn)這個(gè)Cookie,通常不要這樣做。設(shè)置域名的格式如下:domain=http://xyz.com
path
設(shè)置對(duì)于特定的服務(wù)器來(lái)說(shuō)哪個(gè)目錄中的網(wǎng)頁(yè)可訪問(wèn)Cookie,設(shè)置path的格式是:path=/movies
Expires
設(shè)置Cookie存活的時(shí)間,默認(rèn)情況下,用戶關(guān)閉瀏覽器則Cookie自動(dòng)刪除,如果沒(méi)有設(shè)置Cookie失效的時(shí)間,那么用戶關(guān)閉瀏覽器時(shí)Cookie也消失。如果設(shè)置該項(xiàng),就能延長(zhǎng)Cookie的生命期。設(shè)置時(shí)間在JS 中用Date對(duì)象的GMT形式,格式如下: expires=date.toGMTString()
Secure
取true或者false值。如果為true,那么必須通過(guò)https發(fā)送Cookie。
在JS中,可以使用Document對(duì)象的cookie屬性操作cookie。JS 可以讀取,創(chuàng)建,修改和刪除當(dāng)前網(wǎng)頁(yè)的cookie,,來(lái)看看具體的騷操作。
創(chuàng)建 Cookie
JS可以使用document.cookie屬性創(chuàng)建cookie,可以通過(guò)以下方式創(chuàng)建cookie:
document.cookie="username=Daisy Green";
還可以添加有效日期(UTC 時(shí)間)。默認(rèn)情況下,在瀏覽器關(guān)閉時(shí)會(huì)刪除 cookie:
document.cookie="username=Daisy Green; expires=Mon, 26 Aug 2019 12:00:00 UTC";
通過(guò) path 參數(shù),可以告訴瀏覽器 cookie 屬于什么路徑。默認(rèn)情況下,cookie 屬于當(dāng)前頁(yè)。
document.cookie="username=Daisy Green; expires=Mon, 26 Aug 2019 12:00:00 UTC"; path=/";
讀取 Cookie
通過(guò) JS,可以這樣讀取 cookie:
var x=document.cookie;
document.cookie 會(huì)在一條字符串中返回所有 cookie,比如:cookie1=value; cookie2
事例:
<html> <head> <script type="text/javascript"> <!-- function ReadCookie() { var allcookies=document.cookie; document.write ("All Cookies : " + allcookies ); // Get all the cookies pairs in an array cookiearray=allcookies.split(';'); // Now take key value pair out of this array for(var i=0; i<cookiearray.length; i++) { name=cookiearray[i].split('=')[0]; value=cookiearray[i].split('=')[1]; document.write ("Key is : " + name + " and Value is : " + value); } } //--> </script> </head> <body> <form name="myform" action=""> <p> click the Button to View Result:</p> <input type="button" value="Get Cookie" onclick="ReadCookie()"/> </form> </body> </html>
運(yùn)行:
改變 cookie
通過(guò)使用 JS,咱們可以像創(chuàng)建 cookie 一樣改變它:
document.cookie="username=Steve Jobs; expires=Sun, 31 Dec 2017 12:00:00 UTC; path=/";
這樣舊 cookie 會(huì)被覆蓋。
事例:
<html> <head> <script type="text/javascript"> <!-- function WriteCookie() { var now=new Date(); now.setMonth( now.getMonth() + 1 ); cookievalue=escape(document.myform.customer.value) + ";" document.cookie="name=" + cookievalue; document.cookie="expires=" + now.toUTCString() + ";" document.write ("Setting Cookies : " + "name=" + cookievalue ); } //--> </script> </head> <body> <form name="myform" action=""> Enter name: <input type="text" name="customer"/> <input type="button" value="Set Cookie" onclick="WriteCookie()"/> </form> </body> </html>
運(yùn)行:
刪除 cookie
刪除 cookie 非常簡(jiǎn)單,不必指定 cookie 值:直接把 expires 參數(shù)設(shè)置為過(guò)去的日期即可:
document.cookie="username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
應(yīng)該定義 cookie 路徑以確保刪除正確的 cookie。如果不指定路徑,有些瀏覽器不會(huì)讓咱們刪除 cookie。
事例:
<html> <head> <script type="text/javascript"> <!-- function WriteCookie() { var now=new Date(); now.setMonth( now.getMonth() - 1 ); cookievalue=escape(document.myform.customer.value) + ";" document.cookie="name=" + cookievalue; document.cookie="expires=" + now.toUTCString() + ";" document.write("Setting Cookies : " + "name=" + cookievalue ); } //--> </script> </head> <body> <form name="myform" action=""> Enter name: <input type="text" name="customer"/> <input type="button" value="Set Cookie" onclick="WriteCookie()"/> </form> </body> </html>
參考:https://www.w3schools.com/js/js_cookies.asp
我是小智,公眾號(hào)「大遷世界」作者,對(duì)前端技術(shù)保持學(xué)習(xí)愛(ài)好者。我會(huì)經(jīng)常分享自己所學(xué)所看的干貨,在進(jìn)階的路上,共勉!
關(guān)注公眾號(hào),后臺(tái)回復(fù)福利,即可看到福利,你懂的。
如果小伙伴最近有訪問(wèn)國(guó)外的一些標(biāo)準(zhǔn)網(wǎng)站的話,可能經(jīng)常會(huì)彈出一個(gè)對(duì)話框,說(shuō)是本網(wǎng)站為了更好的體驗(yàn)和跟蹤,需要訪問(wèn)你的cookies,問(wèn)你同意不同意,對(duì)于這種比較文明的做法,我一般是點(diǎn)同意的。
但是轉(zhuǎn)頭一想,為什么訪問(wèn)國(guó)內(nèi)的網(wǎng)站從來(lái)沒(méi)有彈出過(guò)這個(gè)提示呢?這是一個(gè)值得深思的問(wèn)題,或許當(dāng)你看完這篇文章之后,就有了答案。
那么cookies有什么作用呢?HTTP cookies就是服務(wù)器端發(fā)送給瀏覽器端的一小部分?jǐn)?shù)據(jù),瀏覽器接收到這個(gè)數(shù)據(jù)之后,可以存起來(lái)自己用,也可以在后續(xù)發(fā)送到server端進(jìn)行一些數(shù)據(jù)的校驗(yàn)。
通過(guò)在cookies中存儲(chǔ)一些有用的數(shù)據(jù),可以將無(wú)狀態(tài)的HTTP協(xié)議變成有狀態(tài)的session連接,或者用來(lái)保存登錄的權(quán)限,下次不用密碼即可登陸,非常有用。
一般來(lái)說(shuō),cookies用在三個(gè)方面:
在很久很久以前,還沒(méi)有現(xiàn)代瀏覽器的時(shí)候,客戶端的唯一存儲(chǔ)就是cookies,所以cookies也作為客戶端存儲(chǔ)來(lái)使用的,但是有了現(xiàn)代的瀏覽器之后,一般是建議把客戶端存儲(chǔ)的數(shù)據(jù)放到其他存儲(chǔ)方式中。
為什么呢?
因?yàn)槊看握?qǐng)求cookies中的數(shù)據(jù)會(huì)自動(dòng)帶上,并且發(fā)送到server端,所以如果cookies中存儲(chǔ)了太多的數(shù)據(jù),就會(huì)導(dǎo)致服務(wù)器性能的下降。
因?yàn)閏ookies是客戶端的本地存儲(chǔ),所以如果服務(wù)器端想要設(shè)置客戶端的cookies時(shí),通過(guò)在響應(yīng)頭中設(shè)置Set-Cookie,瀏覽器接收到這個(gè)響應(yīng)頭之后,就會(huì)將對(duì)應(yīng)的cookies內(nèi)容存儲(chǔ)到瀏覽器本地。
然后在后續(xù)的服務(wù)器請(qǐng)求中都會(huì)帶上Cookie header。同時(shí)cookie還可以帶上過(guò)期時(shí)間、發(fā)送限制等屬性。
先來(lái)看下Set-Cookie的格式:
Set-Cookie: <cookie-name>=<cookie-value>
舉個(gè)例子,下面是一個(gè)server端的響應(yīng):
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: name=flydean
Set-Cookie: site=www.flydean.com
當(dāng)瀏覽器接收到這個(gè)響應(yīng)之后,就會(huì)在本地的cookies中設(shè)置對(duì)應(yīng)的值,并且在后續(xù)的請(qǐng)求中將這些值以cookies的header形式帶上:
GET /test.html HTTP/2.0
Host: www.flydean.com
Cookie: name=flydean; site=www.flydean.com
在netty中提供了一個(gè)Cookie的類,專門用來(lái)表示cookies,這個(gè)類中提供了cookies的基本屬性,然后通過(guò)使用:
response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
來(lái)對(duì)響應(yīng)頭進(jìn)行設(shè)置。
HTTP的cookies有兩種,一種是session cookies,這種cookies會(huì)在session結(jié)束之后自行刪除。
還有一種cookies通過(guò)指定Expires或者 Max-Age 來(lái)設(shè)置過(guò)期時(shí)間:
Set-Cookie: id=abcdef; Expires=Thu, 31 May 2021 08:00:00 GMT;
其中Expires是HTTP1.0中定義的header,Max-Age是HTTP1.1中定義的header。
HTTP提供了兩個(gè)屬性來(lái)對(duì)cookies的權(quán)限進(jìn)行控制,分別是Secure和HttpOnly。
如果cookies中帶有Secure屬性,那么cookies只會(huì)在使用HTTPS協(xié)議的時(shí)候發(fā)送給服務(wù)器。如果使用的是HTTP協(xié)議,則不會(huì)發(fā)送cookies信息。
并且,如果是在http的情況下,server端是不允許給cookie設(shè)置Secure屬性的。
但是設(shè)置了Secure屬性并不意味著cookies就是安全的,因?yàn)榭梢詮钠渌氖侄文玫綖g覽器端的cookies。
還有一個(gè)屬性是HttpOnly,如果cookies設(shè)置了HttpOnly,那么cookies是不允許被JavaScript訪問(wèn)的,通過(guò)設(shè)置HttpOnly,我們可以提升客戶端數(shù)據(jù)的安全性:
Set-Cookie: id=abcdef; Expires=Thu, 21 May 2021 08:00:00 GMT; Secure; HttpOnly
cookies還可以添加Domain和Path屬性,用于標(biāo)記cookies可以發(fā)送到的URL。
其中Domain表示域名,而Path表示路徑。
如果Domain沒(méi)有設(shè)置,則默認(rèn)是設(shè)置cookies的host,這個(gè)host是不包含子domain的。如果手動(dòng)指定了Domain,那么子domain是會(huì)包含在內(nèi)的。
比如如果我們?cè)O(shè)置了Domain=flydean.com,那么子domain:doc.flydean.com也會(huì)共享這個(gè)cookies。
Path用來(lái)匹配URL的路徑,只有匹配到的URL才可以發(fā)送cookies。
另外HTTP還提供了一個(gè)SameSite屬性,表示如果是在CORS環(huán)境情況下,是否發(fā)送cookies到第三方網(wǎng)站,這樣可以在一定程度上保護(hù)網(wǎng)站的信息。
SameSite有三個(gè)可能的值,分別是Strict, Lax, 和 None。如果在Strict情況下,那么cookie僅發(fā)送到與創(chuàng)建它的站點(diǎn)相同的站點(diǎn)。Lax跟Strict類似,不同之處在于當(dāng)用戶導(dǎo)航到cookie的原始站點(diǎn)時(shí)發(fā)送cookie,比如通過(guò)訪問(wèn)外部站點(diǎn)的鏈接。 None可以在原始網(wǎng)站和跨站資源訪問(wèn)中使用,但是必須要在安全的環(huán)境中進(jìn)行(設(shè)置Secure屬性)。如果沒(méi)有設(shè)置SameSite,那么表現(xiàn)是和Lax一致的。
例如:
Set-Cookie: name=flydean; SameSite=Strict
我們知道cookies是和domain相關(guān)的,如果cookies的domain是和當(dāng)前訪問(wèn)的頁(yè)面相同的話,這個(gè)cookies就叫做 first-party cookies。如果和當(dāng)前的訪問(wèn)頁(yè)面不同,比如訪問(wèn)第三方的圖片、腳本、css等,第三方的服務(wù)器有可能會(huì)發(fā)送他們自己的cookies,這種cookies叫做第三方cookies,第三方cookies主要被用來(lái)廣告或者跟蹤用戶的行為信息。
對(duì)于有些瀏覽器來(lái)說(shuō),可能會(huì)禁用第三方的cookies,這有可能會(huì)導(dǎo)致訪問(wèn)網(wǎng)站的一些功能問(wèn)題,大家可以主要觀察一下。
使用cookies可以輔助我們做很多事情,但是也要注意cookies的安全性。
本文已收錄于 http://www.flydean.com/05-http-cookie/
最通俗的解讀,最深刻的干貨,最簡(jiǎn)潔的教程,眾多你不知道的小技巧等你來(lái)發(fā)現(xiàn)!
歡迎關(guān)注我的公眾號(hào):「程序那些事」,懂技術(shù),更懂你!
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。