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>

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

  • 相关阅读:
    如何只通过Sandboxed Solution启动一个定时执行的操作
    创建与SharePoint 2010风格一致的下拉菜单 (续) 整合Feature Custom Action框架
    创建与SharePoint 2010风格一致的下拉菜单
    《SharePoint 2010 应用程序开发指南》第二章预览
    SharePoint 2013 App 开发 (1) 什么是SharePoint App?
    使用Jscex增强SharePoint 2010 JavaScript Client Object Model (JSOM)
    搜索范围的管理
    SharePoint 2010 服务应用程序(Service Application)架构(1)
    SharePoint 2010 服务应用程序(Service Application)架构(2)
    SharePoint 2013 App 开发 (2) 建立开发环境
  • 原文地址:https://www.cnblogs.com/zhangkunweb/p/6538308.html
Copyright © 2011-2022 走看看