同一网站不同和二级域名和不同子目录的cookie

 

1、cookie二级域名的实现:

用户其中一个站点登录,而且可以各个子频道间切换,保持登录状态设置Cookie时,使用如下代码即可:
setcookie(name,value,expire,path,"domain.com");
这样,在每个二级域名都能读取这个Cookie的值。 参见:

cookie共享于二级域名

http://lonvea.iteye.com/blog/1160577

一个cookie如上4个重要的属性:

1)maxAge:cookie被客户端保持的时间,单位为(秒),正数表示在指定的秒数后过期被客户端删除,0表示删除此cookie(置空),负数则表示此cookie不会被客户端存储,将在浏览器关闭后清除.

2)domain:cookie可被有效操作的域,可以为ip/hostname等,不过需要声明:*.abc.com,.abc.com,abc.com这三种方式会有区别,客户端会做简单的匹配.多数情况下直接使用abc.com可以接受多级子域名.只有正确匹配domain的cookie才会被发送给server.

3)secure:是否只允许安全加密url访问,默认为false,如果为true,那么cookie只对https/SSL等加密连接才会发送给server.

4)path:cookie对domain何路径下访问有效,"/"表示domain下根目录中所有请求有效,"/open"表示只对domain/open目录下请求有效,如果此path忘记设置,你将遇到一个很尴尬的问题:明明在其他页面设置了cookie输出,但是换个页面却死活不行..

 

domain和path是决定可跨域的2个参数.

对于domain,"abc.com"则可以在abc.com主域名之下的多级子域名有效,".abc.com"只能在二级域名以及"www.abc.com"下有效,其实客户端只是做了简单的匹配..你可以在此基础上做更多的分级控制..

path是个有参考意义的属性,对于部分路径下开放访问的系统有意义,比如:abc.com/open下的程序和登录是开放给特殊开发者接入的,这里的数据活着cookie需要做一些另类的处理..


 

2、同一网站不同子目录的cookie要设置path,才能互相访问。参见: 

cookie path

http://www.cnblogs.com/ainiaa/archive/2011/11/18/2253841.html

以前使用cookie的时候 没有在意path的问题。这次公司商城实现了静态化的功能,多了2级目录。导致了我在商品详情页面设置好的cookie(path为/good/商品ID/)在店铺首页竟然访问不到(店铺首页的path为'/store/')。cookie的名称都是一致的。唯一不同的只有path。在商品详情页设置cookie的时候吧path设置成‘/’,这样修改之后就可以正常的在店铺首页取到设置好的cookie了。

使用关键字 javascript cookie  path 还搜索到了,原来10年来IE一直存在一个cookie path的一个bug(原文地址:http://conkeyn.iteye.com/blog/423549)。

 

手上一个广告项目,在Firefox下顺利测试通过。自信JS代码能兼容IE,FF测试过后随手就仍给CS测试,结果CS反馈说有问题。排查一番, 发现居然和Javascript 设置 Cookie 时的 path 有关。IE下Cookie种在 /或者URL所在路径时正常,如果Cookie值作用域在当前URL下则IE下javascript 无法获取到设置的Cookie值。

看下面演示代码:

 

  1. var cookie_name = "name";  
  2. var cookie_value = "value";  
  3. expires = new Date();  
  4. expires.setTime(expires.getTime() + 86400 * 1000);  
  5.   
  6. // 有Bug document.cookie无法独到cookie_name值  
  7. document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)  
  8.         + "; expires=" + expires.toGMTString() + "; path="  
  9.         + window.location.pathname;  
  10. // 正常  
  11. document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)  
  12.         + "; expires=" + expires.toGMTString() + "; path=/test/";  
  13. // 正常  
  14. document.cookie = "cookie_name=" + encodeURIComponent(cookie_value)  
  15.         + "; expires=" + expires.toGMTString() + "; path=/";  

 

怀疑是IE的Bug、
在google上 搜了下关键词: ie javascript cookie path bug 
同样的问题在罪与罚 的博客上也有描述,而且博主联系过微软IEBLOG 的Eric。得到的回复是:

You have uncovered an IE bug where cookies that are set with a path that contains a filename (e.g. /page.htm) are not accessible to the document.cookie function, although they are correctly sent to the server in the HTTP header. This has been broken for at least 10 years and unfortunately probably will not be fixed in IE8.

Thanks,

-Eric

一个存在10年的Bug。。。而且IE8也不会修复,实在是无语。

需求是cookie值只对当前页面有效,没办法只好用替代方案,看代码:

 

  1. //IE Cookie Bug 替代方案  
  2. var cookie_path = window.location.pathname;  
  3. var cookie_name = encodeURIComponent(cookie_path.substring(cookie_path  
  4.         .lastIndexOf('/') + 1));  
  5. cookie_path = cookie_path.substring(0, cookie_path.lastIndexOf('/') + 1);  
  6. var cookie_value = "value";  
  7. expires = new Date();  
  8. expires.setTime(expires.getTime() + 86400 * 1000);  
  9.   
  10. document.cookie = cookie_name + "=" + encodeURIComponent(cookie_value)  
  11.         + "; expires=" + expires.toGMTString() + "; path=" + cookie_path;  

 替代方案根据每个页面的URL文件名来做Cookie名,有效范围在当前页路经下。
如:url 等于 /test/test.html
则cookie名为test.html,有效路径为/test/
这样也可以做到同一个js部署在每个页面上能读到只对当前URL有效的cookie值。代价是当用户在同一级目录下访问很多页面时会导致cookie值不 断增大。结果是当前路径下的每个http请求都带很长一段的cookie,直接导致服务器接收客户端request的header长度增长,流量增长的同 时服务器负担也变重。而且根据 RFC 2109 的定义Cookie也有长度和个数限制,IE允许的最大 Cookie 长度是 4096 字节,允许50个 Cookie 名-值对。如果要突破50个名-值对的限制,可以在一个名-值使用Cookie字典的方式保存更多的Cookie变量。

http://blog.seateng.cn/archives/2009/03/ie-javascript-cookie-path-bug.html

这次的静态化功能让我学到了cookie的这个问题。很是高兴啊。

这次静态化功能还涉及到了一个跨域请求的问题。事情是这样的:

我在搜索模块(域名search.emall.xxx.xxx)需要显示当前用户的商品浏览历史。二者个商品浏览历史是在主站的cookie里面存储的。为了方便我们把COOKIE_DOMAIN都设置成了一样的一级域名,使用js的cookie却不能获得设置好的cookie。但是,使用firebug + firecookie却可以清楚的看到cookie是存在的且没有过期。唯一不同的就好似cookie的domain和当前模块的domain一致(cookie是在主站设置好的emall.xxx.xxx,当前search的域名为search.emall.xxx.xxx)。 这很容易就让人想到是cookie domain的问题导致的。问题原因找到了,解决它。使用js不行我就我就使用ajax的方式请求主站,在主站吧cookie取出来,然后再原样的返回。编码,运行,反先,ajax请求还是不能获得(使用get的方式发送请求)。把ajax请求的地址放在地址栏里面,确实有内容返回,但是使用ajax请求的话,还是不能获得cookie的值。很显然,这种情况就是传说中的跨域请求的问题。这问题咱没有解决过,怎么办那?突然想起来了,该模块下用户登录信息就是通过ajax异步取出来的。同时ajax请求为什么用户的登录信息可以拿到我的为什么就拿不到???

找原因。找到请求用户信息的代码,才发现,原来请求的时候和我的ajax还有一点不一样。请求用户信息的方式为:

JS代码如下:

复制代码
    //跨域获取数据
jQuery.ajax({
type : "GET",
url : temp_domain_url+"/index.php?",
data : "act=get_user_info&php_session_id="+jQuery.cookie('COOKIE_ID')+"&jsoncallback=?",
dataType : "jsonp",
jsonnp : 'callback',
success:function(data){
      ...
      ...
      ...
    }
  });
复制代码

php代码如下:

复制代码
function get_user_info()
{
$gbh_goods_info = $_COOKIE['gbh_goods_info'] ? $_COOKIE['gbh_goods_info'] : json_encode(false);
if ($gbh_goods_info && get_magic_quotes_gpc())
{//没有这个的话会出现错误
$gbh_goods_info = stripslashes($gbh_goods_info);
}
$gbh_goods_info = json_decode($gbh_goods_info);
echo $_GET['callback']."({msg: ".json_encode($gbh_goods_info)."});";
exit;
}
复制代码

这才弄明白到底是什么原因了。

照着葫芦画瓢终于吧功能实现了。。。。

 

posted @ 2014-08-01 13:19  忘忧般若汤  阅读(8321)  评论(1编辑  收藏  举报