字数:1293
阅读时间:5分钟
##简介
cookie语法:
Cookie:<cookie-list>
Cookie:name=value;
Cookie:name=value; name1=value1; name2=value2
在使用cookie之前,我们先清晰一个概念:cookie是http请求的请求首部属性之一,是通过服务端或者脚本设置的保存于浏览器客户端中的信息。如果用户手动在浏览器中设置了禁用cookie,我们就无法使用它了。
它的语法就是一系列的名称值对用=操作符连接,然后每一对名称值对之间使用分号+空格隔开。
因浏览器同源策略,我们是无法跨域操作cookie的。
我们会用它存储一些简单的临时的信息,例如登录令牌。
##JS中操作cookie
在JS中,我们可以通过document全局对象提供的接口来操作cookie。
语法:
let strCookies = document.cookie; //获取cookie
document.cookie = strCookies; //更新cookie
strCookies的值就是上述的cookie语法形式。不过属性值后面可以跟上如下配置数据,使用分号为分隔。
-;path=path
配置cookie的路径,默认为当前文档的路径。document.cookie可以获取到当前路径和子路径的信息。
-domain=domain
配置cookie的域名,默认为当前域。document.cookie无法获取不同域的信息。
-max-age=max-age-in-seconds
设置当前cookie的保留时间,单位为妙,默认cookie会在当前会话关闭(即浏览器关闭)时失效。
-expires=date-in-GMTString-format
设置当前cookie保留到哪个时间点,接收GMTString的日期格式数据,默认cookie会在当前会话关闭(即浏览器关闭)时失效。
-;secure
设置cookie在https时才生效。
这里,我们要注意一下几点:
①cookie的值中是不允许出现任何逗号、分号或空格,所以cookie值可以使用encodeURIComponent()
来转换一次。
②max-age
是在http1.1中用来取代expires
出现的新属性,ie9以下不支持max-age。当同时存在max-age和expires时,会自动忽略掉expires。因此,这里建议两个属性都维护一下。
下面,我们引用MDN中的一个操作cookie的示例为例,尝试一下cookie的正确操作方式。
var CookieOper = { /** * 获取cookie值 * @param {String} sKey cookie名称 * @return {String} cookie值 */ getItem: function (sKey) { if (!sKey) { return null; } return decodeURIComponent(document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1')) || null; }, /** * 设置cookie值 * @param {String} sKey cookie名称 * @param {String} sValue cookie值 * @param {Number|String|Date} vEnd 保留时间 * @param {String} sPath 路径 * @param {String} sDomain 域 * @param {Boolean} bSecure 是否开启安全协议 */ setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) { if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; } var sExpires = ''; if (vEnd) { switch (vEnd.constructor) { case Number: sExpires = vEnd === Infinity ? '; expires=Fri, 31 Dec 9999 23:59:59 GMT' : '; max-age=' + vEnd; break; case String: sExpires = '; expires=' + vEnd; break; case Date: sExpires = '; expires=' + vEnd.toUTCString(); break; } } document.cookie = encodeURIComponent(sKey) + '=' + encodeURIComponent(sValue) + sExpires + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : '') + (bSecure ? '; secure' : ''); return true; }, /** * 删除cookie * @param {String} sKey cookie名称 * @param {String} sPath 路径 * @param {String} sDomain 域 */ removeItem: function (sKey, sPath, sDomain) { if (!this.hasItem(sKey)) { return false; } document.cookie = encodeURIComponent(sKey) + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' + (sDomain ? '; domain=' + sDomain : '') + (sPath ? '; path=' + sPath : ''); return true; }, /** * 是否拥有对应名称的cookie * @param {String} sKey cookie名称 * @return {Boolean} 是否拥有cookie */ hasItem: function (sKey) { if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; } return (new RegExp('(?:^|;\\s*)' + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=')).test(document.cookie); }, /** * 获取所有cookie名称 * @return {Array} 名称集合 */ keys: function () { var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, '').split(/\s*(?:\=[^;]*)?;\s*/); for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); } return aKeys; }};
其他的都好理解,需要注意的是,删除cookie是设置cookie过时即可,并非我们惯性的删除操作。然后设置cookie的名称和值的时候注意使用encodeURIComponent方法转换一下。
使用不同的参数测试接口结果如下:
//document.cookie = "key1=value1"CookieOper.setItem('key1', 'value1');//document.cookie = "key1=value1; key2=value2"//一分钟到期CookieOper.setItem('key2', 'value2', 60);//document.cookie = "key1=value1; key2=value2"//无法通过 document.cookie 获取到不同路径下的cookie信息,//但是可以获取到当前路径下子目录的信息CookieOper.setItem('key3', 'value3', null, '/dir/');//删除失败CookieOper.removeItem('key3', '/dir/');//document.cookie = "key1=value1; key2=value2"//当前域中的cookie不会变化//这里文档的访问地址为:lp:8020CookieOper.setItem('key4', 'value4', null, null, '11.lp');//document.cookie = "key1=value1; key2=value2"//由于当前地址并没有使用https,所以cookie设置无法生效。CookieOper.setItem('key4', 'value4', null, null, null, true);
注意事项
①由于用户可以设置禁用cookie,所以在使用cookie时,我们需要考虑到这种情况。
②不要跨域使用cookie。
③对于https协议的网页,我们需要加上secure
参数。
④最好是同时维护好max-age和expires。
⑤设置cookie名称和值的时候,使用encodeURIComponent函数转换一下。
参考资料
欢迎关注我的微信公众号: