• JavaScript操作cookie基础分析


    简要介绍

    cookie是什么cookie是HTTP协议的一部分。HTTP Cookie(也叫Web cookie或者浏览器Cookie)是服务器发送到用户浏览器并保存在浏览器上的一块数据,它会在浏览器下一次发起请求时被携带并发送到服务器上。

    因为HTTP协议是无状态的,所以需要一种存储数据的机制。

    cookie以键值对的方式存储数据。

    一般浏览器对cookie的大小和数量都有限制,大小4KB,数量20个。

    cookie既可以通过后端语言读写,也可以通过JS等在前端读写。

    推荐的一种标准时间字符串格式:1970-01-01T00:00:00.000Z。(精确到毫秒,T和Z仅仅一种格式字符)

    调试cookie需要在服务器环境下
    Chrome浏览器可以在打开控制台在Application -> Storage -> Cookies 看到浏览器cookie设置的信息
    FireFox浏览器可以单击 右键 -> 查看页面信息 -> 安全 -> 查看cookie

    用到的函数

    把标准字符串时间转成GMT时间

    标准字符串时间长的像这样:2017-08-17T00:00:00.000Z
    GMT时间长的像这样:Thu, 17 Aug 2017 00:00:00 GMT

    实现

    function toGmtTime(stdStrTime) {
        var mTime = Date.parse(stdStrTime);
        var dateObj = new Date(mTime);
        var gmtTime = dateObj.toUTCString();
        return gmtTime;
    }
    // 测试
    var time = "2017-08-17T00:00:00.000Z";
    gmtTime = toGmtTime(time);
    console.log(gmtTime); // Thu, 17 Aug 2017 00:00:00 GMT
    

    描述
    toGmtTime()可以把一个标准字符串时间转成GMT时间,以供后面cookie参数用。标准字符串时间这个名字是我自己起的,为叙述方便。GMT时间这是我在控制台打印出来的标准格式。

    encodeURIComponent()

    语法

    encodeURIComponent(str);
    

    参数:待转义的字符串
    返回值:转义后的字符串

    功能解释
    encodeURIComponent 可以转义除了下列字符以外的所有字符:

    A-Z a-z 0-9 - _ . ! ~ * ' ( )
    

    使用示例

    var set1 = ";,/?:@&=+$";  // Reserved Characters
    var set2 = "-_.!~*'()";   // Unescaped Characters
    var set3 = "#";           // Number Sign
    var set4 = "ABC abc 123"; // Alphanumeric Characters + Space
    
    console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24
    console.log(encodeURIComponent(set2)); // -_.!~*'()
    console.log(encodeURIComponent(set3)); // %23
    console.log(encodeURIComponent(set4)); // ABC%20abc%20123
    

    decodeURICompent()

    语法

    decodeURIComponent(encodedURI)
    

    参数:encodeURI, 就是被encodeURIComponent转义后的字符串
    返回值:返回被转义前的字符串

    使用示例

    var str = "ABC%20abc%20123";
    console.log(decodeURIComponent(str)); // ABC abc 123
    
    document.cookie = "name=value; path=path; domain=domain; max-age=max-age-in-seconds; expires=date-in-GMTString-format; secure";
    

    示例

    document.cookie = "usr=XiaoMing";
    document.cookie = "usr=MiYue1; path=/";
    document.cookie = "usr=MiYue2; path=/; domain=localhost";
    document.cookie = "usr=MiYue3; path=/; domain=localhost; max-age=5";
    document.cookie = "usr=MiYue4; path=/; domain=localhost; expires=Thu, 17 Aug 2017 00:00:00 GMT";
    document.cookie = "usr=MiYue5; path=/; domain=localhost; expires=Thu, 17 Aug 2048 00:00:00 GMT; secure";
    

    描述
    document.cookie基本上是JS提供的操作cookie的唯一接口,该属性可读可写。要注意这个属性和一般的属性不太一样,每次给document.cookie设置新的值都代表新增,不会覆盖以前设置好的cookie。读取时,只能一次性读取所设置的全部cookie。

    参数解释

    name
    必不可少,不可省略。不能包含逗号,分号,空格。一般用encodeURIComponent()进行转义。

    value
    必不可少,不可省略。同name一样,也需用encodeURIComponent()进行转义。

    path
    可以省略。省略后表示cookie的有效路径为当前文件所在的目录。/表示根目录,PHP服务器环境下就是www目录。path参数如果要自己设置,不能随便设置,我在Chrome控制台调试时,发现只能将path设置为,当前文件的父级目录或者设置为根目录,换成其它目录都会导致该条cookie失效。

    domain
    可以省略。默认cookie生效域名,为当前域名。

    name、path、domain 3个要素才能唯一的表示1个cookie

    max-age
    可以省略。设置cookie多少秒后过期,与expires参数2选1用即可。默认有效时间是会话关闭时失效。(我在Chrome浏览器里测试,关闭浏览器一个标签不会导致cookie失效,点击浏览器右上角的X,完全关闭浏览器,cookie才会失效。)设置了此参数,如果用Chrome 控制台查看cookie信息,看到过期时间那一栏,仍是标准字符串时间的形式,这是浏览器自动计算并显示出来的。(注意8个小时的时差)

    expires
    可以省略。指定cookie在什么时间失效,这需要一个GMT时间。

    secure
    可以省略。设置cookie的传输协议为https.(设置完毕后在Chrome控制台里好像看不出什么效果,但是在FireFox中可以看到效果。)

    如上所述JS 原生操作cookie的接口非常渣,下面我们自己实现几个方便操作cookie的函数。

    function setCookie (name, value, stdStrTime, maxAge, path, domain, secure) {
        var cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    
        if (stdStrTime) {
            var mTime = Date.parse(stdStrTime);
            var dateObj = new Date(mTime);
            var gmtTime = dateObj.toUTCString();
            cookie += '; expires=' + gmtTime;
        }
        if (maxAge) {
            cookie += '; max-age=' + maxAge;
        }
        if (path) {
            cookie += '; path=' + path;
        }
        if (domain) {
            cookie += '; domain=' + domain;
        }
        if (secure) {
            cookie += '; secure';
        }
    
        document.cookie = cookie;
    }
    
    // 把document.cookie转成对象
    function getCookie () {
        var cookie = {};
        var all = document.cookie;
    
        if (all === '') {
            return cookie;
        }
    
        var list = all.split('; ');
    
        for (var i = 0; i < list.length; i++) {
            var item = list[i];
            var p = item.indexOf('=');
            var name = item.substring(0, p);
            name = decodeURIComponent(name);
            var value = item.substring(p + 1);
            value = decodeURIComponent(value);
            cookie[name] = value;
        }
        return cookie;
    }
    
    // 删除某个cookie实质上是修改某个cookie的max-age为0,使其失效
    function removeCookie (name, path, domain) {
        document.cookie = name + '='
        + '; path=' + path
        + '; domain=' + domain
        + '; max-age=0';
    }
    
    // 添加cookie
    setCookie('usr1', 'MiYue1');
    setCookie('usr2', 'MiYue2', 0);
    setCookie('usr3', 'MiYue3', '2018-08-08T00:00:00.000Z');
    setCookie('usr4', 'MiYue4', 0, 0);
    setCookie('usr5', 'MiYue5', 0, '3600');
    setCookie('usr6', 'MiYue6', 0, 0, '/');
    setCookie('usr7', 'MiYue7', 0, 0, 0, 'localhost');
    
    // 把document.cookie转成对象
    var cookie = getCookie();
    console.log(cookie.usr3);
    
    // 删除指定cookie
    removeCookie('usr6', '/', 'localhost');
    console.log(cookie);
    

    上面的函数我没有测试设置secure参数的情况,不知什么原因secure总是不生效。

    参考链接

    MDN cookie 介绍
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
    https://developer.mozilla.org/zh-CN/docs/Web/API/Document/cookie

    Cookie specification: RFC 6265
    https://tools.ietf.org/html/rfc6265

  • 相关阅读:
    如何在TVM上集成Codegen(上)
    CodeGen准备存储库
    CodeGen按钮循环
    CodeGen标记循环
    CodeGen结构循环回路
    CodeGen处理Synergy方法目录
    回顾6 单点登录
    回顾 five 幂等性
    回顾 four Object
    程序员的数学基础课 笔记6
  • 原文地址:https://www.cnblogs.com/asheng2016/p/7374884.html
Copyright © 2020-2023  润新知