天天看点

前端基础(七):cookie操作

字数:1293

阅读时间:5分钟

简介

cookie语法:

Cookie:

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 = ; 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', );

//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:8020
CookieOper.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函数转换一下。

参考资料

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cookie

https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie

https://blog.csdn.net/eroswang/article/details/8302191

欢迎关注我的微信公众号: