好程序員web前端分享Cookie知識

  好程序員web前端分享Cookie知識,今天小編爲你們帶來了一篇新手必看乾貨,接下來讓咱們一塊兒來看一看吧。
  1、Cookie的出現
  瀏覽器和服務器之間的通訊少不了HTTP協議,可是由於HTTP協議是無狀態的,因此服務器並不知道上一次瀏覽器作了什麼樣的操做,這樣嚴重阻礙了交互式Web 應用程序的實現。
  針對上述的問題,網景公司的程序員創造了Cookie。
  2、Cookie的傳輸
  服務器端在實現Cookie標準的過程當中,須要對任意HTTP請求發送Set-Cookie HTTP頭做爲響應的一部分:
  1. Set-Cookie: name=value; expires=Tue, 03-Sep-2019 14:10:21 GMT; path=/; domain=.xxx.com;
  瀏覽器端會存儲這樣的Cookie,而且爲以後的每一個請求添加Cookie HTTP請求頭髮送回服務器:
  1. Cookie: name=value
  服務器經過驗證Cookie值,來判斷瀏覽器發送請求屬於哪個用戶。
  3、瀏覽器中的Cookie
  瀏覽器中的Cookie主要由如下幾部分組成:
  · 名稱:Cookie惟一的名稱,必須通過URL編碼處理。(同名會出現覆蓋的狀況)
  · 值:必須通過URL編碼處理。
  · 域(domain):默認狀況下cookie在當前域下有效,你也能夠設置該值來確保對其子域是否有效。
  · 路徑(path):指定Cookie在哪些路徑下有效,默認是當前路徑下。
  · 失效時間(expires):默認狀況下,瀏覽器會話結束時會自動刪除Cookie;也能夠設置一個GMT格式的日期,指定具體的刪除日期;若是設置的日期爲之前的日期,那麼Cookie會當即刪除。
  · 安全標誌(secure):指定以後只容許Cookie發送給https協議。
  瀏覽器在發送請求時,只會將名稱與值添加到請求頭的Cookie字段中,發送給服務端。
  瀏覽器提供了一個很是蹩腳的API來操做Cookie:
  1. document.cookie
  經過上述方法能夠對該Cookie進行寫操做,每一次只能寫入一條Cookie字符串:
  1. document.cookie = 'a=1; secure; path=/'
  經過該方法還能夠進行Cookie的讀操做:
  1. document.cookie // "a=1"
  因爲上述方法操做Cookie很是的不直觀,通常都會寫一些函數來簡化Cookie讀取、設置和刪除操做。
  對於Cookie的設置操做中,須要如下幾點:
  對於名稱和值進行URL編碼處理,也就是採用JavaScript中的encodeURIComponent()方法; expires要求傳入GMT格式的日期,須要處理爲更易書寫的方式,好比:設置秒數的方式; 注意只有的屬性名的secure;
  每一段信息須要採用分號加空格。
  1. function setCookie (key, value, attributes) {
  2. if (typeof document === 'undefined') {
  3. return
  4. }
  5. attributes = Object.assign({}, {
  6. path: '/'
  7. }, attributes)
  8.
  9. let { domain, path, expires, secure } = attributes
  10.
  11. if (typeof expires === 'number') {
  12. expires = new Date(Date.now() + expires * 1000)
  13. }
  14. if (expires instanceof Date) {
  15. expires = expires.toUTCString()
  16. } else {
  17. expires = ''
  18. }
  19.
  20. key = encodeURIComponent(key)
  21. value = encodeURIComponent(value)
  22.
  23. let cookieStr = ${key}=${value}
  24.
  25. if (domain) {
  26. cookieStr += ; domain=${domain}
  27. }
  28.
  29. if (path) {
  30. cookieStr += ; path=${path}
  31. }
  32.
  33. if (expires) {
  34. cookieStr += ; expires=${expires}
  35. }
  36.
  37. if (secure) {
  38. cookieStr += ; secure
  39. }
  40.
  41. return (document.cookie = cookieStr)
  42.}
  Cookie的讀操做須要注意的是將名稱與值進行URL解碼處理,也就是調用JavaScript中的decodeURIComponent()方法:
  1. function getCookie (name) {
  2. if (typeof document === 'undefined') {
  3. return
  4. }
  5. let cookies = []
  6. let jar = {}
  7. document.cookie && (cookies = document.cookie.split('; '))
  8.
  9. for (let i = 0, max = cookies.length; i < max; i++) {
  10. let [key, value] = cookies[i].split('=')
  11. key = decodeURIComponent(key)
  12. value = decodeURIComponent(value)
  13. jar[key] = value
  14. if (key === name) {
  15. break
  16. }
  17. }
  18.
  19. return name ? jar[name] : jar
  20.}
  最後一個清除的方法就更加簡單了,只要將失效日期(expires)設置爲過去的日期便可:
  1. function removeCookie (key) {
  2. setCookie(key, '', { expires: -1 })
  3. }
  介紹Cookie基本操做的封裝以後,還須要瞭解瀏覽器爲了限制Cookie不會被惡意使用,規定了Cookie所佔磁盤空間的大小以及每一個域名下Cookie的個數。
  4、服務端的Cookie
  相比較瀏覽器端,服務端執行Cookie的寫操做時,是將拼接好的Cookie字符串放入響應頭的Set-Cookie字段中;執行Cookie的讀操做時,則是解析HTTP請求頭字段Cookie中的鍵值對。
  與瀏覽器最大的不一樣,在於服務端對於Cookie的安全性操碎了心
  signed
  當設置signed=true時,服務端會對該條Cookie字符串生成兩個Set-Cookie響應頭字段:
  1. Set-Cookie: lastTime=2019-03-05T14:31:05.543Z; path=/; httponly
  2. Set-Cookie: lastTime.sig=URXREOYTtMnGm0b7qCYFJ2Db400; path=/; httponly
  這裏經過再發送一條以.sig爲後綴的名稱以及對值進行加密的Cookie,來驗證該條Cookie是否在傳輸的過程當中被篡改。
  httpOnly
  服務端Set-Cookie字段中新增httpOnly屬性,當服務端在返回的Cookie信息中含有httpOnly字段時,開發者是不能經過JavaScript來操縱該條Cookie字符串的。
  這樣作的好處主要在於面對XSS(Cross-site scripting)攻擊時,黑客沒法拿到設置httpOnly字段的Cookie信息。
  此時,你會發現localStorage相比較Cookie,在XSS攻擊的防護上就略遜一籌了。 sameSite
  在介紹這個新屬性以前,首先你須要明白:當用戶從http://a.com發起http://b.com的請求也會攜帶上Cookie,而從http://a.com攜帶過來的Cookie...
  雖然第三方Cookie有一些好處,可是給CSRF(Cross-site request forgrey)攻擊的機會。
  爲了從根源上解決CSRF攻擊,sameSite屬性便閃亮登場了,它的取值有如下幾種:
  · strict:瀏覽器在任何跨域請求中都不會攜帶Cookie,這樣能夠有效的防護CSRF攻擊,可是對於有多個子域名的網站採用主域名存儲用戶登陸信息的場景,每一個子域名都須要用戶從新登陸,形成用戶體驗很是的差。
  · lax:相比較strict,它容許從三方網站跳轉過來的時候使用Cookie。
  爲了方便你們理解sameSite的實際效果,能夠看這個例子:
  1. // a.com 服務端會在訪問頁面時返回以下Cookie
  2. cookies.set('foo', 'aaaaa')
  3. cookies.set('bar', 'bbbbb')
  4. cookies.set('name', 'cccccc')
  5.
  6. // b.com 服務端會在訪問頁面時返回以下Cookie
  7. cookies.set('foo', 'a', { sameSite: 'strict' })
  8. cookies.set('bar', 'b', { sameSite: 'lax' })
  9. cookies.set('baz', 'c')
  如何如今用戶在a.com中點擊連接跳轉到b.com,它的請求頭是這樣的:
  1. Request Headers
  2.
  3. Cookie: bar=b; baz=c
  5、網站性能優化
  Cookie在服務端和瀏覽器的通訊中,主要依靠HTTP的響應頭和請求頭傳輸的,因此Cookie會佔據必定的帶寬。
  前面提到瀏覽器會爲每一次HTPP請求自動攜帶上Cookie信息,可是對於同站內的靜態資源,服務器並不須要處理其攜帶的Cookie,這無形中便浪費了帶寬。
  在最佳實踐中,通常都會將靜態資源部署到獨立的域名上,從而能夠避免無效Cookie的影響。
  但願本篇文章可以對正在從事Web 前端工做和準備從事Web 前端學習的小夥伴們有所幫助。前端

相關文章
相關標籤/搜索