者:ConardLi 來源:code秘密花園
轉載地址:https://mp.weixin.qq.com/s/7aWSZtitdOuMrRaxMZoYVQ
ookie 為 Web 應用程序保存用戶相關信息提供了一種有用的方法。例如,當用戶訪問咱們的站點時,可以利用 Cookie 保存用戶首選項或其他信息,這樣,當用戶下次再訪問咱們的站點時,應用程序就可以檢索以前保存的信息。
Cookie 是一小段文本信息,伴隨著用戶請求和頁面在 Web 服務器和瀏覽器之間傳遞。用戶每次訪問站點時,Web 應用程序都可以讀取 Cookie 包含的信息。
Cookie的出現是為了解決保存用戶信息的問題。例如
Cookie 能在所有網頁中記住用戶的信息。它以字符串的形式包含信息,并鍵值對的形式保存的,即key=value的格式。各個cookie之間一般是以“;”分隔。
username=Daisy Green
服務器以cookie的形式向訪問者的瀏覽器發送一些數據。如果瀏覽器允許接受 cookie。則將其作為純文本記錄存儲在訪問者的硬盤上。
當訪問者跳轉到另一個頁面時,瀏覽器會將相同的cookie發送到服務器進行檢索。一旦檢索到它,您的服務器就知道或記得以前存儲了什么。
Cookie 在HTTP的頭部Header信息中,HTTP Set-Cookie的Header格式如下:
Set-Cookie: name=value; [expires=date]; [path=path]; [domain=domainname]; [secure];
在HTTP代碼中一個具體的例子:
<meta http-equiv="set-cookie" content=" cookieName=cookieValue; expires=01-Dec-2006 01:14:26 GMT; path=/" />
從上面的格式可以看出,Cookie由下面幾部分組成。
Name/Value對
Name/Value由分號分隔,一個Cookie最多有20對,每個網頁最多有一個Cookie,Value的長度不超過4K。對于Value值,最好用encodeURIComponent對其編碼。
Domain
Domain域名也是Cookie的一部分,默認情況下,用戶訪問網頁的域名會存放在Cookie中。如果設置了這個Cookie的域名值,那么意味著域名上的所有服務器,而不僅是你正在訪問的服務器,都能訪問這個Cookie,通常不要這樣做。設置域名的格式如下:domain=http://xyz.com
path
設置對于特定的服務器來說哪個目錄中的網頁可訪問Cookie,設置path的格式是:path=/movies
Expires
設置Cookie存活的時間,默認情況下,用戶關閉瀏覽器則Cookie自動刪除,如果沒有設置Cookie失效的時間,那么用戶關閉瀏覽器時Cookie也消失。如果設置該項,就能延長Cookie的生命期。設置時間在JS 中用Date對象的GMT形式,格式如下: expires=date.toGMTString()
Secure
取true或者false值。如果為true,那么必須通過https發送Cookie。
在JS中,可以使用Document對象的cookie屬性操作cookie。JS 可以讀取,創建,修改和刪除當前網頁的cookie,,來看看具體的騷操作。
創建 Cookie
JS可以使用document.cookie屬性創建cookie,可以通過以下方式創建cookie:
document.cookie="username=Daisy Green";
還可以添加有效日期(UTC 時間)。默認情況下,在瀏覽器關閉時會刪除 cookie:
document.cookie="username=Daisy Green; expires=Mon, 26 Aug 2019 12:00:00 UTC";
通過 path 參數,可以告訴瀏覽器 cookie 屬于什么路徑。默認情況下,cookie 屬于當前頁。
document.cookie="username=Daisy Green; expires=Mon, 26 Aug 2019 12:00:00 UTC"; path=/";
讀取 Cookie
通過 JS,可以這樣讀取 cookie:
var x=document.cookie;
document.cookie 會在一條字符串中返回所有 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>
運行:
改變 cookie
通過使用 JS,咱們可以像創建 cookie 一樣改變它:
document.cookie="username=Steve Jobs; expires=Sun, 31 Dec 2017 12:00:00 UTC; path=/";
這樣舊 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>
運行:
刪除 cookie
刪除 cookie 非常簡單,不必指定 cookie 值:直接把 expires 參數設置為過去的日期即可:
document.cookie="username=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
應該定義 cookie 路徑以確保刪除正確的 cookie。如果不指定路徑,有些瀏覽器不會讓咱們刪除 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
我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的干貨,在進階的路上,共勉!
關注公眾號,后臺回復福利,即可看到福利,你懂的。
如果小伙伴最近有訪問國外的一些標準網站的話,可能經常會彈出一個對話框,說是本網站為了更好的體驗和跟蹤,需要訪問你的cookies,問你同意不同意,對于這種比較文明的做法,我一般是點同意的。
但是轉頭一想,為什么訪問國內的網站從來沒有彈出過這個提示呢?這是一個值得深思的問題,或許當你看完這篇文章之后,就有了答案。
那么cookies有什么作用呢?HTTP cookies就是服務器端發送給瀏覽器端的一小部分數據,瀏覽器接收到這個數據之后,可以存起來自己用,也可以在后續發送到server端進行一些數據的校驗。
通過在cookies中存儲一些有用的數據,可以將無狀態的HTTP協議變成有狀態的session連接,或者用來保存登錄的權限,下次不用密碼即可登陸,非常有用。
一般來說,cookies用在三個方面:
在很久很久以前,還沒有現代瀏覽器的時候,客戶端的唯一存儲就是cookies,所以cookies也作為客戶端存儲來使用的,但是有了現代的瀏覽器之后,一般是建議把客戶端存儲的數據放到其他存儲方式中。
為什么呢?
因為每次請求cookies中的數據會自動帶上,并且發送到server端,所以如果cookies中存儲了太多的數據,就會導致服務器性能的下降。
因為cookies是客戶端的本地存儲,所以如果服務器端想要設置客戶端的cookies時,通過在響應頭中設置Set-Cookie,瀏覽器接收到這個響應頭之后,就會將對應的cookies內容存儲到瀏覽器本地。
然后在后續的服務器請求中都會帶上Cookie header。同時cookie還可以帶上過期時間、發送限制等屬性。
先來看下Set-Cookie的格式:
Set-Cookie: <cookie-name>=<cookie-value>
舉個例子,下面是一個server端的響應:
HTTP/2.0 200 OK
Content-Type: text/html
Set-Cookie: name=flydean
Set-Cookie: site=www.flydean.com
當瀏覽器接收到這個響應之后,就會在本地的cookies中設置對應的值,并且在后續的請求中將這些值以cookies的header形式帶上:
GET /test.html HTTP/2.0
Host: www.flydean.com
Cookie: name=flydean; site=www.flydean.com
在netty中提供了一個Cookie的類,專門用來表示cookies,這個類中提供了cookies的基本屬性,然后通過使用:
response.headers().add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie));
來對響應頭進行設置。
HTTP的cookies有兩種,一種是session cookies,這種cookies會在session結束之后自行刪除。
還有一種cookies通過指定Expires或者 Max-Age 來設置過期時間:
Set-Cookie: id=abcdef; Expires=Thu, 31 May 2021 08:00:00 GMT;
其中Expires是HTTP1.0中定義的header,Max-Age是HTTP1.1中定義的header。
HTTP提供了兩個屬性來對cookies的權限進行控制,分別是Secure和HttpOnly。
如果cookies中帶有Secure屬性,那么cookies只會在使用HTTPS協議的時候發送給服務器。如果使用的是HTTP協議,則不會發送cookies信息。
并且,如果是在http的情況下,server端是不允許給cookie設置Secure屬性的。
但是設置了Secure屬性并不意味著cookies就是安全的,因為可以從其他的手段拿到瀏覽器端的cookies。
還有一個屬性是HttpOnly,如果cookies設置了HttpOnly,那么cookies是不允許被JavaScript訪問的,通過設置HttpOnly,我們可以提升客戶端數據的安全性:
Set-Cookie: id=abcdef; Expires=Thu, 21 May 2021 08:00:00 GMT; Secure; HttpOnly
cookies還可以添加Domain和Path屬性,用于標記cookies可以發送到的URL。
其中Domain表示域名,而Path表示路徑。
如果Domain沒有設置,則默認是設置cookies的host,這個host是不包含子domain的。如果手動指定了Domain,那么子domain是會包含在內的。
比如如果我們設置了Domain=flydean.com,那么子domain:doc.flydean.com也會共享這個cookies。
Path用來匹配URL的路徑,只有匹配到的URL才可以發送cookies。
另外HTTP還提供了一個SameSite屬性,表示如果是在CORS環境情況下,是否發送cookies到第三方網站,這樣可以在一定程度上保護網站的信息。
SameSite有三個可能的值,分別是Strict, Lax, 和 None。如果在Strict情況下,那么cookie僅發送到與創建它的站點相同的站點。Lax跟Strict類似,不同之處在于當用戶導航到cookie的原始站點時發送cookie,比如通過訪問外部站點的鏈接。 None可以在原始網站和跨站資源訪問中使用,但是必須要在安全的環境中進行(設置Secure屬性)。如果沒有設置SameSite,那么表現是和Lax一致的。
例如:
Set-Cookie: name=flydean; SameSite=Strict
我們知道cookies是和domain相關的,如果cookies的domain是和當前訪問的頁面相同的話,這個cookies就叫做 first-party cookies。如果和當前的訪問頁面不同,比如訪問第三方的圖片、腳本、css等,第三方的服務器有可能會發送他們自己的cookies,這種cookies叫做第三方cookies,第三方cookies主要被用來廣告或者跟蹤用戶的行為信息。
對于有些瀏覽器來說,可能會禁用第三方的cookies,這有可能會導致訪問網站的一些功能問題,大家可以主要觀察一下。
使用cookies可以輔助我們做很多事情,但是也要注意cookies的安全性。
本文已收錄于 http://www.flydean.com/05-http-cookie/
最通俗的解讀,最深刻的干貨,最簡潔的教程,眾多你不知道的小技巧等你來發現!
歡迎關注我的公眾號:「程序那些事」,懂技術,更懂你!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。