摘要:前言大概是我的業務領域比較狹窄的原因我總是會聽說卻很少在實際的開發中應用或者實踐過它今天剛好看到高級程序設計第三版的數據存儲部分說到了這里就對做一個深入訪談希望和我一樣對似曾相識的朋友可以真正的熟悉并學會利用來服務我們的業務定義是服務器為了
前言
大概是我的業務領域比較狹窄的原因,我總是會聽說cookie,卻很少在實際的開發中應用或者實踐過它,今天剛好看到<
cookie,是服務器為了辨別用戶身份,進行session跟蹤而存儲在用戶本地終端上的數據(通常經過加密).
限制域名限制
因為cookie一般用于與服務器進行交互,所以它一般存放在對應的域名下.當設定了一個cookie后,再給創建它的域名發送請求時,都會包含這個cookie,這個限制確保了儲存在cookie中的信息只能讓批準的接受者訪問,而無法被其他域訪問.
個數限制
由于cooki是存儲在客戶端計算機上的,還加入了一些限制確保cookie不會被惡意使用,同時不會占據太多磁盤空間.每個域的cookie總數是有限的,不過瀏覽器之間各有不同.
IE7和之后的版本每個域名最多50個.
Firefox限制每個域最多50個cookie
Opera限制每個域最多30個cookie
Safari 和Chrome 對每個域的cookie數量沒有硬性規定.
當超過單個域名限制之后還要在設置cookie,瀏覽器會清除以前設置的cookie.IE和Opera會刪除最近最少使用過的cookie.所以考慮cookie限制非常重要,避免出現不可預期的后果.
尺寸限制
瀏覽器中對于cookie的尺寸也有限制,大多數瀏覽器是4KB的長度限制,尺寸限制影響一個域下所有的cookie,而并非每個cookie多帶帶限制.
如果你嘗試創建查過最大限制的cookie,那么該cookie會被悄無聲息地丟掉.
cookie由瀏覽器保存的以下幾塊信息構成.
名稱(name): 一個唯一確定cookie的名稱.
值(value): 存儲在cookie中的字符串值.
域(domain): cookie對于哪個域是有效的,控制只有向該域發送的請求才會包含這個cookie.
路徑(path): 對于指定域中的哪個路徑,應該向服務器發送cookie.
失效時間(expires): 表示cookie何時會被刪除的時間戳,沒有設置則默認是瀏覽器會話結束時,即將所有cookie刪除,若設置的失效日期是以前的時間,則cookie會被立刻刪除.
安全標志(secure): 制定后,cookie只有在使用SSL鏈接的時候才會發送到服務器,即https請求才可以發送cookie.
注意發送cookie的時候只會發送cookie的名和值才會被發送,其他值只會cookie信息的描述.
cookie的使用 使用場景常用場景: cookie一般用來做登錄驗證,用戶登陸的時候講用戶名和密碼傳入到服務器端,服務器會返回將用戶相關的認證信息,然后由服務器將這些信息寫入cookie或者由前端使用js操作cookie將這些信息寫入到cookie中(如果服務器通過Set-Cookie的方式直接寫入則不需要前端的參與,前端是無感知的),登陸成功以后的用戶在該域名下的訪問都會在請求中發送cookie,作為該用戶的身份標識.我們這里主要討論的是前端使用js操作cookie的情況.
不常用場景: 我們也可以用js操作cookie,在cookie上存儲我們臨時需要的用于頁面交互的變量,這個時候cookie就充當了sessionStorage或者localStorage的角色.
操作cookie由于JavaScript中讀寫cookie不是非常直觀,常常需要寫一些函數來簡化cookie的功能.基本的操作有三種: 讀取,寫入,刪除;
說明: 我不知道看這篇文章的朋友是不是了解這些操作cookie的方法,如果不了解,我建議你先想一想,然后嘗試著自己去寫,然后感興趣的話再來看看我的代碼,也可以分享到評論區,我們一起來看看這些實現方法的優劣,不知道不同思想的碰撞會不會擦出奇妙的火花呢? 很期待奧~
封裝的操作cookie的代碼如下:
const CookieUtil = { // 獲取cookie 接受的參數 cookie的名稱 get: function(name) { var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null; if(cookieStart !== -1) { var cookieEnd = document.cookie.indexOf(";",cookieStart); if(cookieEnd == -1) { cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.LENGTH, cookieEnd)); } return cookieValue; }, // 設置cookie, 接收參數: cookie的名稱, cookie的值, // 可選的用于執行cookie何時應被刪除的Date對象,cookie的可選的URL路徑, 可選的域和是否要添加secure標志的布爾值 set: function (name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value); if(expires instanceof Date) { cookieText += "; expires=" + expires.toGMTString(); } if(path) { cookieText += "; path=" + path; } if(domain) { cookieText += "; domain=" + domain; } if(secure) { cookieText += "; secure"; } document.cookie = cookieText; }, // 刪除cookie的方法, 接收的參數: 要刪除的cookie的名稱,可選的路徑參數,可選的域參數和可選的安全參數 unset: function (name, path, domain, secure) { // 將某個cookie的過期時間早于當前時間,則會被立刻刪除,該方法設置失效時間為1970年1月1日 this.set(name, "", new Date(0), path, domain, secure); } } // 設置cookie CookieUtil.set("name", "Nicholas"); CookieUtil.set("book", "Professional JavaScript"); // 讀取cookie的值 CookieUtil.get("name"); CookieUtil.get("book"); // 刪除cookie CookieUtil.unset("name"); CookieUtil.unset("book");子cookie
為了繞開瀏覽器的單域名下的cookie數限制,一些開發人員使用了一種成為子cookie的改變,子cookie是存放在單個cookie中的更小段的數據,通常是多個名稱值對的形式.子cookie對常見的格式如下所示:
namename1=value1&name2=value2&name3=value3&name4=value4&name5=value5
子cookie一般也以查詢字符串的格式進行格式化,然后這些值可以使用單個cookie進行儲存和訪問,而非對每個名稱-值對兒使用不同的cookie存儲,最后網站或者web應用程序可以無需大到單域名cookie上限也可以存儲更加結構化的數據.
為了更好的操作子cookie,必須建立一系列新方法,子cookie的解析和序列化會因子cookie的期望用途而略有不同并更加復雜些,例如,要獲得一個子cookie,首先要遵循與獲得cookie一樣的基本步驟,但是在解碼cookie值之前,需要操作字符串,遍歷數組之類的操作來找出子cookie的信息.
說明: 我不知道看這篇文章的朋友是不是了解這些操作cookie的方法,如果不了解,我建議你先想一想,然后嘗試著自己去寫,然后感興趣的話再來看看我的代碼,也可以分享到評論區,我們一起來看看這些實現方法的優劣,不知道不同思想的碰撞會不會擦出奇妙的火花呢?
操作子cookie的方法如下:
// 操作子cookie的一組方法 var SubCookieUtil = { // 獲取cookie, 接收兩個參數,cookie名和子cookie名 // 如果不穿子cookie名,則是普通的獲取方法,如果傳了,則取對應子cookie名的value. get: function (name, subName) { var subCookies = this.getAll(name); if(subCookies) { return subCookies[subName]; } else { return null; } }, // 判斷如果cookie中name對應的value不包含子cookie, // 則返回解碼后的cookieValue,如果包含子cookie,則返回處理后的result對象 getAll: function (name) { var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieEnd, result={}, cookieValue= null, i,len,subCookies="", parts = []; if(cookieStart !== -1) { cookieEnd = document.cookie.indexOf(";", cookieStart); if(cookieEnd == -1) { cookieEnd = document.cookie.length; } cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd); if(cookieValue.length > 0) { if(cookieValue.indexOf("&") > -1) { subCookies = cookieValue.split("&"); console.log("get subCookies",subCookies); for(i = 0,len = subCookies.length; i < len; i++) { parts = subCookies[i].split("="); result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]); } } else { parts = cookieValue.split("="); result[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]) } return result; } } return null; }, // 同樣的,要設置子cookie,也有新的set方法 set: function(name, subName, value, expires, path, domain, secure) { var subCookies = this.getAll(name) || {}; subCookies[subName] = value; this.setAll(name, subCookies, expires, path, domain, secure); }, setAll: function(name, subCookies, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=", subCookieParts = [], sub, result; // 將subCookies對象里的cookie值對編碼,并放進subCookieParts數組中 for(sub in subCookies) { if(subCookies.hasOwnProperty(sub)) { subCookieParts.push(encodeURIComponent(sub)+ "=" + encodeURIComponent(subCookies[sub])); } } if(subCookieParts.length > 0) { cookieText += subCookieParts.join("&"); if(expires instanceof Date) { cookieText += "; expires=" + expires.toGMTString(); } } else { cookieText += "; expires=" + (new Date(0)).toGMTString(); } if(path) { cookieText += "; path=" + path; } if(domain) { cookieText += "; domain=" + domain; } if(secure) { cookieText += "; secure"; } document.cookie = cookieText; }, // 刪除cookie 刪除單個cookie unset: function(name, subName, path, domain, secure) { var subCookies = this.getAll(name); subCookies[subName] ? delete subCookies[subName] : ""; this.setAll(name, subCookies, null, path, domain, secure); }, //刪除cookie 刪除多個cookie unsetAll: function (name, path, domain, secure) { this.setAll(name, null, new Date(0), path, domain, secure); } } // 假設 document.cookie = "data=name=Nicholas&book=Professional%20JavaScript" // 設置兩個cookie SubCookieUtil.set("xiaosisi", "name", "Nicholas"); SubCookieUtil.set("xiaosisi", "book", "Professional JavaScript"); SubCookieUtil.set("xiaosisi", "sisisi", "撕撕撕"); // 設置全部子cookie和失效日期 SubCookieUtil.setAll("xiaosisi", {name: "Nicholas", book:"Professional JavaScript", sisisi: "撕撕撕"}, new Date("2018-10-25")); // 修改名字的值,并修改失效日期 SubCookieUtil.setAll("xiaosisi", "name", "MIrascl", new Date("2018-11-25")); // 刪除名為sisisi的子cookie SubCookieUtil.unset("xiaosisi", "sisisi"); // 刪除整個cookie SubCookieUtil.unsetAll("xiaosisi");總結
關于cookie有兩點需要注意的地方:
第一: 由于所有的cookie都會由瀏覽器作為請求頭發送,所以在cookie中存儲大量信息會影響到特定域的請求性能,cookie信息越大,完成對服務器請求的時間也就越長.盡管瀏覽器對cookie的大做了限制,不過最好還是盡可能在cookie中少存儲信息,以免影響性能.
第二:一定不要在cookie中存儲重要和敏感的數據.cookie的存儲不是很安全,其中包含的任何數據都可以被他人訪問,重要的用戶信息不建議存儲在cookie里.
如果讀者們有關于cookie的比較好的使用策略歡迎在評論區留言或者私信我奧~共同進步是最讓人開心的事兒呢~~~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95448.html
寫在最前:BFC看起來是個很陌生的概念但它卻時時發生在我們工作中,如何清除浮動影響?如何避免margin穿透問題?如何編寫兩欄自適應布局?都和BFC有這密不可分的關系,下面走進切圖妞的世界,分分鐘搞定BFC! 一、什么是BFC? BFC概念 塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是塊盒子的布局過程發生的區域,也是浮動元素...
寫在最前:BFC看起來是個很陌生的概念但它卻時時發生在我們工作中,如何清除浮動影響?如何避免margin穿透問題?如何編寫兩欄自適應布局?都和BFC有這密不可分的關系,下面走進切圖妞的世界,分分鐘搞定BFC! 一、什么是BFC? BFC概念 塊格式化上下文(Block Formatting Context,BFC) 是Web頁面的可視化CSS渲染的一部分,是塊盒子的布局過程發生的區域,也是浮動元素...
閱讀 955·2019-08-30 14:24
閱讀 987·2019-08-30 14:13
閱讀 1799·2019-08-29 17:21
閱讀 2661·2019-08-29 13:44
閱讀 1654·2019-08-29 11:04
閱讀 438·2019-08-26 10:44
閱讀 2564·2019-08-23 14:04
閱讀 908·2019-08-23 12:08