关于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.com,erp.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