zoukankan      html  css  js  c++  java
  • cookie 详解 与 封装 实用的cookie

    在WEB前端开发中,cookie是必不可少的,网上也有很多开源的库可以使用,不过我还是想自己总结一下,做个笔记并封装一个实用的库。

    (1)什么是cookie?

    从web 角度 cookie是用于存储信息为下次访问 或者 与服务器之间传递信息的,

    它可以记住用户上次操作了什么,操作到哪里了,为智能的操作提供基础。

    它有自己的操作方式,有自己的大小,不过它的操作方式不太方便,可以依赖第三方库(下面我自己封装了一个)。

    (2)cookie的基础知识点:

    它有大小限制,一般不超过4kb,超出的将不再保存。

    cookie 是不安全的,能通过查看cookies 或者 与服务器传递的header 中看到,所以不能报存重要的私密信息,如 用户的密码。

    cookie 有自己的过期时间,可以用它来清除cookie。

    cookie 保存的是字符串,多个cookies 之间用 ‘; ’分割,注意分号后还有一个空格,cookie 的key和value之间是“=”相连。

    cookie 有其他高级存储方式如:path,domain,secure;

    (3)cookie的简单操作:

    1.存储和修改cookie:
    document.cookie = 'key=value';
    2.删除cookie:
    document.cookie = 'key=value;expires=过去的时间.toUTCString()';
    (4)cookie的高级操作:
    1.过期时间(expires)
        cookie 不是对象,不能通过操作对象的方式删除某个cookie,你可能会说把value设置为null或者undefined可以吗?答案是不可以,设置了null/undefined 获取的值
    就是null/undefined,
    这条cookie是一直存在,并没有删除。如下图:


       expires 的作用就在此刻显示了出来,通过设置过期时间可以删除这条cookie,同时也可以把过期时间延迟,从而延长这个cookie存在的时间,默认情况下,
    expires 是 session,关闭浏览器cookie清除。
    由于上面说过,cookie是String 类型的,那保存的时间格式也只能是字符串类型的,我们可以用toUTCString()把时间格式化成字符串,我们也可以
    用toGMTString(),
    不过toGTMString()已经被toUTCString代替了(来自w3c),

    2.路径(path)
    path默认是当前浏览网页的父级文件夹,我们可以通过设置path 实现跨多个文件共用这条cookie。例如:
    我有这个文件,截图如下:

    我在setCookie.html中写下:

    document.cookie='from=我是来自setCookie;path=/testCookie';

    注意:我把path设置为‘/testCookie’,在getCookie.html中写下:

    console.log('我是twoFile里面的getCookie,获取的cookie是:'+document.cookie);

    设置的结果:

     获取的结果:

    从中可以看出我在one文件夹中设置的cookie,在two文件夹中获得了。

    3.域(domain)
    cookie 可以通过设置domain实现同域访问,前提是path='/',这里一定要注意是同域,而非跨域。
    比如 http://news.baidu.com 与 https://www.baidu.com ,
    如果想设置同域访问,设置如下:

     document.cookie = 'key=value;path=/;domain=baidu.com';
        
    4.安全(secure)

    我上面说了,cookie是不安全的,为何cookie有个安全(secure)呢?
    其实大家不要误解了这个安全,如果设置了secure ,则保证 cookie 与服务器之间的数据传输过程加密,但是保存在本地的并没有发生任何改变,
    有人说那我可以前端加密,算我没说,后面我们在聊聊前端加密问题,现在仅仅谈论secure的作用,
    我感觉这个作用不大,搞开发这么长时间了,直到现在没
    有用过,(如有不同意见谢谢批评指出)。
    用法如下:
     document.cookie = 'key=value;secure';

    (5)问题:
    cookie 与服务器传输,怎么传输的,在什么地方看到的,服务器(我用的node.js)如何获得?
    cookie与服务器传输是在Request Headers 中,如下图:

     不过在header中分两种情况:

    1.同域:服务器和web在统一域名下,这种情况下cookie默认是加到header中的,
    2.跨域:服务器和web不在统一域名下,这种情况下就相对复杂了,但是这种情况在实际开发中是最常见的,

    因为前后台分离是大势所趋,人心所向。那我们细细谈谈。其实,跨域下默认header 没有cookie的,原因很明显,那就是相对性的安全,这点也很好理解,
    那问题是,我们如何解决让header中有cookie呢?
     xhr.withCredentials = true;
    加上这段就可以了,这就解决了跨域安全策略,告诉ajax 放心传cookie吧,这个API是可以信赖的,
    注意:如果同域 这个参数是没有用的 无论true或者false(Setting withCredentials has no effect on same-site requests.)。

    前端解决了,问题是,你给cookie,服务器想要么,如果不想要,ajax就会报错(我的片面理解)。服务器若想要cookie,拿node.js为例 设置如下:
    app.all('*', function(req, res, next) {
        res.header("Access-Control-Allow-Credentials", "true");
        res.header("Access-Control-Allow-Origin", "http://localhost:63342");
    });
    特别注意: 给一个带有withCredentials的请求发送响应的时候,服务器端必须指定允许请求的域名,不能使用'*'.上面这个例子中,如果响应头是这样
    的:Access-Control-Allow-Origin: * ,则响应会失败.在这个例子中 Access-Control-Allow-Origin 的值是 http://localhost:63342
    这个指定的请求域名。

    (6)个人认为开发中应用场景

    登录记住两周功能:这个例子,记住的不是用户的帐号和密码,那是不安全的,而是后台根据用户信息、浏览器情况、ip等合成并返回一个用
    户登录标识符(如 uid),记在cookie中,等下次进入或者刷新时,读取这个uid,判断是否已经登录了,并返回登录后应该返回的信息。

    上面的是自己的拙见,若有错误,请无私的批评,谢谢大家!
    好了cookie基本说完了,咱们实战一下,这是我封装的cookie用法:
      1 (function ($window, $document) {
      2     function isUndefined(value) {
      3         return typeof value === 'undefined';
      4     }
      5 
      6     function isDefined(value) {
      7         return typeof value !== 'undefined';
      8     }
      9 
     10     function isString(value) {
     11         return typeof value === 'string';
     12     }
     13 
     14     function getBaseHref() {
     15         var oBase = $document.getElementsByTagName('base')[0];
     16         if (!oBase) {
     17             return '';
     18         }
     19         var href = oBase.getAttribute('href');
     20         return href ? href.replace(/^(https?:)?//[^/]*/, '') : '';
     21     }
     22 
     23     function cookieWriter(key, value, options) {
     24         var path, expires, defaultPath = getBaseHref();
     25         options = options || {};
     26 
     27         path = isDefined(options.path) ? options.path : defaultPath;
     28         if (isUndefined(value)) {
     29             expires = 'Thu, 01 Jan 1970 00:00:00 GMT';
     30         }
     31         if (isString(expires)) {
     32             expires = new Date(expires);
     33         }
     34         var str = encodeURIComponent(key) + '=' + encodeURIComponent(value);
     35         str += expires ? ';expires=' + expires.toUTCString() : '';
     36         str += path ? ';path=' + path : '';
     37         str += options.domain ? ';domain=' + options.domain : '';
     38         str += options.secure ? ';secure' : '';
     39         $document.cookie = str;
     40     }
     41 
     42     function cookiesReader() {
     43         var currentCookie = $document.cookie || '',
     44                 cookie, index, lastCookies = {}, name;
     45 
     46         var cookieArray = currentCookie.split('; ');
     47 
     48         for (var i = 0; i < cookieArray.length; i++) {
     49             cookie = cookieArray[i];
     50             index = cookie.indexOf('=');
     51             if (index > 0) {
     52                 name = decodeURIComponent(cookie.substring(0, index));
     53                 lastCookies[name] = decodeURIComponent(cookie.substring(index + 1));
     54             }
     55         }
     56         return lastCookies;
     57     }
     58 
     59     function getCookieByKey(key) {
     60         var lastCookies = cookiesReader();
     61         for (var i in lastCookies) {
     62             if (i === key) {
     63                 return lastCookies[i];
     64             }
     65         }
     66         return '';
     67     }
     68 
     69     function toJson(value) {
     70         try {
     71             return JSON.parse(value);
     72         } catch (e) {
     73             return value;
     74         }
     75     }
     76 
     77     $window.$cookie = {
     78         //获取cookie
     79         get: function (key) {
     80             return getCookieByKey(key);
     81         },
     82         //获取cookie对象
     83         getObject: function (key) {
     84             return JSON.parse(getCookieByKey(key));
     85         },
     86         //获取全部cookies,allParse 是否完全解析josn
     87         getAll: function (allParse) {
     88             if (!allParse) {
     89                 return cookiesReader();
     90             }
     91             var lastCookies = cookiesReader();
     92 
     93             for (var i in lastCookies) {
     94                 lastCookies[i] = toJson(lastCookies[i]);
     95             }
     96             return lastCookies;
     97         },
     98         //设置或者修改cookie,value是字符串
     99         put: function (key, value, options) {
    100             cookieWriter(key, value, options);
    101         },
    102         //设置或者修改cookie,value是对象
    103         putObject: function (key, value, options) {
    104             value = JSON.stringify(value);
    105             cookieWriter(key, value, options);
    106         },
    107         //移除cookie
    108         remove: function (key) {
    109             cookieWriter(key);
    110         },
    111         //移除全部cookies
    112         removeAll: function () {
    113             var cookies = cookiesReader();
    114             var keys = Object.keys(cookies);
    115             for (var i in keys) {
    116                 this.remove(i);
    117             }
    118         }
    119     };
    120 })(window, document);

       测试代码:

     1 <button id="addBtn">添加</button>
     2 <button id="removeBtn">移除</button>
     3 <button id="getBtn">获取</button>
     4 <script>
     5     var addBtn= document.getElementById('addBtn');
     6     var getBtn=document.getElementById('getBtn');
     7     var removeBtn=document.getElementById('removeBtn');
     8 
     9     addBtn.onclick=function(){
    10         $cookie.put('str','zhang',{path:'/'});
    11         $cookie.putObject('obj',{name:'zhang'},{path:'/'});
    12     };
    13 
    14     getBtn.onclick=function(){
    15         console.log($cookie.getObject('str'));
    16         console.log($cookie.getObject('obj'));
    17         console.log($cookie.getAll(true));
    18     };
    19 
    20     removeBtn.onclick=function(){
    21         $cookie.remove('str');
    22     };
    23 </script>

    上面的是我的总结,如果大家发现什么地方,希望批评指出,共同进步,谢谢大家。

  • 相关阅读:
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.7 @Resource
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.6 CustomAutowireConfigurer
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.5 使用泛型作为自动装配限定符
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.4 使用@Qualifier微调基于注解的自动装配
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.3 使用@Primary微调基于注解的自动装配
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.2 @Autowired
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9.1 @Required
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.9 基于注解的容器配置
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.8.3 使用FactoryBean自定义实例化逻辑
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.8.2 使用BeanFactoryPostProcessor定制配置元数据
  • 原文地址:https://www.cnblogs.com/zhangkunweb/p/6538308.html
Copyright © 2011-2022 走看看