大概是个人业务领域比较狭窄的缘由,我老是会据说cookie,却不多在实际的开发中应用或者实践过它,今天恰好看到<<JavaScript高级程序设计第三版>>的数据存储部分,说到了cookie,这里就对cookie作一个深刻访谈,但愿和我同样对cookie似曾相识的朋友能够真正的熟悉cookie,并学会利用cookie来服务咱们的业务.^_^^_^前端
cookie,是服务器为了辨别用户身份,进行session跟踪而存储在用户本地终端上的数据(一般通过加密).web
域名限制 数组
由于cookie通常用于与服务器进行交互,因此它通常存放在对应的域名下.当设定了一个cookie后,再给建立它的域名发送请求时,都会包含这个cookie,这个限制确保了储存在cookie中的信息只能让批准的接受者访问,而没法被其余域访问.浏览器
个数限制
因为cooki是存储在客户端计算机上的,还加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间.每一个域的cookie总数是有限的,不过浏览器之间各有不一样.安全
当超过单个域名限制以后还要在设置cookie,浏览器会清除之前设置的cookie.IE和Opera会删除最近最少使用过的cookie.因此考虑cookie限制很是重要,避免出现不可预期的后果.服务器
尺寸限制
浏览器中对于cookie的尺寸也有限制,大多数浏览器是4KB的长度限制,尺寸限制影响一个域下全部的cookie,而并不是每一个cookie单独限制.
若是你尝试建立查过最大限制的cookie,那么该cookie会被悄无声息地丢掉.cookie
cookie由浏览器保存的如下几块信息构成.session
注意发送cookie的时候只会发送cookie的名和值才会被发送,其余值只会cookie信息的描述.dom
经常使用场景: cookie通常用来作登陆验证,用户登录的时候讲用户名和密码传入到服务器端,服务器会返回将用户相关的认证信息,而后由服务器将这些信息写入cookie或者由前端使用js操做cookie将这些信息写入到cookie中(若是服务器经过Set-Cookie的方式直接写入则不须要前端的参与,前端是无感知的),登录成功之后的用户在该域名下的访问都会在请求中发送cookie,做为该用户的身份标识.咱们这里主要讨论的是前端使用js操做cookie的状况.函数
不经常使用场景: 咱们也能够用js操做cookie,在cookie上存储咱们临时须要的用于页面交互的变量,这个时候cookie就充当了sessionStorage或者localStorage的角色.
因为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对常见的格式以下所示:
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的比较好的使用策略欢迎在评论区留言或者私信我奥~共同进步是最让人开心的事儿呢~~~