COOKIE详解

homeros    前端    999+ 次    2017-12-12 17:20:26


关于cookie,需要弄明白以下几个问题:

  • cookie是什么?
  • http中与cookie相关的头有哪些?
  • 如何设置/清除cookie的?
  • cookie的过期时间的含义是什么?
  • cookie的域指的是什么?
  • cookie的path指的是什么?
  • cookie的属性secure和httponly是什么含义?
  • erp.imihuan.com下的页面能访问www.imihuan.com下的cookie吗?反过来呢?
  • erp.imihuan.com下的页面能访问oa.imihuan.com下的cookie吗?
  • bj.erp.imihuan.com下的页面能访问erp.imihuan.com下的cookie吗?反过来呢?
  • 设置cookie的domain时,".imihuan.com"和"imihuan.com"有什么区别吗?
  • P3P协议是什么?有什么作用?

cookie是什么

什么是cookie?它是一小段存储在浏览器端的状态数据。

“一小段”是说cookie的大小和数量有限制:大小通常是4k,数量则跟浏览器的版本有关,例如IE和Firefox在同一个域名下最多允许50个cookie。

“状态数据”:是指cookie是有生命周期的,在生命周期里,cookie的值可跨请求、跨页面读写。

http中与cookie相关的头有哪些

响应头:

Set-Cookie: key1=value1; expires=???; path=???; domain=???; secure; httponly

Set-Cookie: key2=value2

可以有多个Set-Cookie头,设置多个cookie

请求头:

Cookie: key1=value1; key2=value2

只有一个Cookie头,多个cookie用分号隔开。

如何设置/清除cookie的?

php中设置cookie的方式有两种:

a. setcookie方法

b. header("Set-Cookie", "...") 方法

javascript中设置cookie的代码参考:

(function ($) {
    $.extend({
        cookie: function (name, value, options) {
            if (typeof value != 'undefined') {
                options = options || {};
                if (value === null) {
                    value = '';
                    options.expires = -1;
                }
                var expires = '';
                if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                    var date;
                    if (typeof options.expires == 'number') {
                        date = new Date();
                        date.setTime(date.getTime() + (options.expires * 1000));
                    } else {
                        date = options.expires;
                    }
                    expires = '; expires=' + date.toUTCString();
                }
                var path = options.path ? '; path=' + (options.path) : '';
                var domain = options.domain ? '; domain=' + (options.domain) : '';
                var secure = options.secure ? '; secure' : '';
                document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
            } else {
                var cookieValue = null;
                if (document.cookie) {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = $.trim(cookies[i]);
                        if (cookie.substring(0, name.length + 1) == (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                            break;
                        }
                    }
                }
                return cookieValue;
            }
        }
    });
})(jQuery);

 

删除cookie只需要把cookie的过期时间设置为比当前时间更小的值即可。

cookie的过期时间

a. 如果在设置cookie时:不设置过期时间,那么cookie在浏览器关闭时会自动清除

b. 如果将cookie的过期时间设置为比浏览器本地时间更小,那么cookie将被清除

c. 如果将cookie的过期时间设置为比浏览器本地时间大,那么在过期之前,浏览器会一直保存该cookie,即使浏览器被关闭了。

cookie的域(domain)

每个域名底下都有自己的cookie。为区分某个cookie属于什么域名,所以cookie都有一个域。

注意,除了子域可以访问父域的cookie外,其他情况下不能跨域访问其它域下的cookie。

什么是子域和父域:

首先,要注意域的取值有两种类型:一种是最前面有个点号,一种是最前面没有点号,例如 带点号的.imihuan.com, .erp.imihuan.com;不带点号的 imihuan.comerp.imihuan.com

不带点号的域都是封闭的域,它们没有子域的概念,但有父域。

带点号的域则有父域和子域,例如 .imihuan.com 是 www.imihuan.com 的父域,也是 erp.imihuan.com 的父域。但 imihuan.com 则不是www.imihuan.com的父域。

同理,.www.imihuan.com并不是erp.imihuan.com 的父域,而是 v1.www.imihuan.com 的父域。

cookie的域默认是当前的域名,不带点号。

设置cookie的domain时候,除了可以设置为当前的域名外,也可以将domain设置为当前域名的父域。跨域设置cookie的操作会被浏览器拒绝,A.com下的PHP或者js不能设置B.com下的cookie。而父域也不能设置子域的cookie。

此外,经测试,在Firefox和chrome下,无论是通过PHP或者JS来显式设置cookie的domain时,浏览器会自动在domain的最前面添加点号。其余浏览器未测试。

强烈建议,也是代码规范:在代码中设置cookie的domain的时候,一定要记得在domain前面加上点号。RFC 2019规范也要求domain前面必须加上点号。

cookie的路径(path)

cookie的路径指的是cookie在某个具体的URL指定的路径下是否可用。

什么是URL指定的路径?

URL路径与Linux中的文件路径很像。

首先所有URL的根路径都是 "/";

而对于 http://www.imihuan.com/girl/index.php,这个URL的路径是"/girl/";

对于 http://www.imihuan.com/girl/2016/index.php,这个URL的路径是"/girl/2016/";

路径 "/girl/2016/" 是 "/girl/" 的子路径。

如果cookie的路径设置为根路径 "/",那么cookie在整个domain下都可见。

如果cookie的路径设置为 "/foo/",那么cookie在路径 /foo/ 以及它的子路径下都可见。

需要注意的是,设置cookie的路径时,路径的取值必须当前页面的路径的子路径。否则修改不生效。

cookie的唯一标识

三元组(cookie名称, domain, path)构成cookie的唯一标识。

设置cookie时,当且仅当名称、domain、path三个属性都与一个已存在cookie的相等时,会修改已存在cookie。否则,会创建一个新的cookie。

特别需要注意的是,设置cookie路径时,路径 "/foo" 和 "/foo/" 是不一样的,浏览器会认为是两个不同的cookie。因此,一般要求path必须以斜杠结束。

同样,设置cookie的域时,".imihuan.com"和"imihuan.com"也是不一样的,浏览器会认为是两个不同的cookie。因此,一般要求domain必须以点号开头。

cookie的属性secure和httponly

secure:表示该cookie必须在https下才可见。http页面中的javascript也无法访问该cookie。

httponly:表示该cookie只能通过HTTP协议访问。这意味着无法使用javascript来访问或修改httponly的cookie。

P3P协议

P3P: Platform for Privacy Preferences 隐私设置平台规范,用来声明你的网站的隐私策略。

使用PHP来设置P3P头:

header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');  

P3P头中有许多3个或4个字母组成一个个标签,分别代表了你的声明的隐私策略,例如NOI 表示不搜集可识别用户的资料,ADM 表示信息搜集会用于网站管理,等等。

P3P协议可以用来解决跨域设置cookie的问题。

什么是跨域设置cookie?首先要明确的是,不是说在A.com中直接设置域为B.com的cookie。

跨域设置cookie场景如下:

假设我有一个页面,域名是 www.A.com/index.php , 在页面中嵌套了一个iframe,iframe的src是 www.B.com/p3p.php ,p3p.php的功能是在域名www.B.com中设置一个cookie,这个cookie又通常被称为第三方的cookie。在某些浏览器下(尤其是IE浏览器),会阻止p3p.php中设置的cookie。

此时,我们可以在p3p.php页面响应中设置P3P头,浏览器看到对应的P3P头后,会允许设置第三方的cookie。

从法律的角度,如果你的网站的使用了P3P头,但实际上你又没有遵循你在P3P头中所声明的隐私策略,是会被起诉的。

但事实上,即使像google这样的大公司,它一样使用P3P头来解决跨域设置cookie的问题。但google又担心被用户起诉,所以它怎么做呢?它使用一些不合法的P3P标签,从而来绕开IE的限制,但又没有违反P3P协议。

参考:http://www.cylab.cmu.edu/research/techreports/2010/tr_cylab10014.html


上一篇: php & mysql代码优化建议

下一篇: javascript中的作用域链

最新评论

暂无评论

热门文章

最新评论

网站数据

网站文章数:483

今日UV/PV/IP:15/16/15

昨日UV/PV/IP:11/17 /14

TOP