很早以前在chrome上实现了使用js动态生成第三方网站的ajax登陆窗口,一开始只是自己用并未对其他浏览器兼容。直到今天在IE8上实现的时候发现表单能正常提交,但是登陆状态怎么也保存不了。同样的代码在chrome下是完全可以的,并且通过chrome的Network查看确定cookie写入成功。于是,使用httpwatch对IE进行抓包,发现IE也接收到后端发送过来的setcookie请求,然后就没有然后了,cookie根本就没保存!
可是,当我将登陆get传参的url通过IE直接访问时却百试不爽,每一次都能正确保存cookie。这时就纳闷了,唯一的不同就是一个使用iframe,另外一个没有使用iframe。果然,当使用ie iframe搜索之后,不小心看到以前一个同学的博客里好像有解决方案。
主要有2种解决方案:第一种是在IE的高级隐私设置中接受第三方Cookie。(哎,原来还真是IE的毛病,但是这个方案不能采用!);第二种是P3P协议,这个在后端返回一个header就能让IE跨域接受第三方cookie,这个正是我所想要的。可以参考下面的内容:
浏览器的第三方 cookie 限制
所谓第三方 cookie,就是说你访问网页 A,却接收到域名 B 的 cookie 设定指令。这可能是由于网页 A 请求或链接了 B 的网页,比如上面提到的 iframe 以及 jsonp。
我查到了各个浏览器对于跨域的处理规则,可以看到第三方 cookie ,IE 在默认设置中是做了限制的。不同浏览器的第三方 cookie 规则IEFIREFOXCHROMESAFARIOPERA
限制第三方coookie是否否是否
要解决这个问题,有 2 种方法,一个就是上面说到的调整 IE 设置,将第三方域名加入到可信网站列表中;另一个方法,就是 P3P 了。
P3P?
P3P 全称 Platform for Privacy Preferences,隐私设定平台规范。这个规范极其复杂,若要讲清楚,天都黑了一半。简言之,就是网站向浏览器声明自己的隐私政策,比如网站是否搜集访问者的个人信息,设置 cookie 的用途等等。浏览器会依据设置,决定在第三方请求的条件下是否接受网站的 cookie。
完整地部署 P3P 包括设立隐私政策文件(policy.html)、原则档(policy.xml)、参考档(p3p.xml),有兴趣详细了解的可以参考 MSDN 中关于部署 P3P的文章。
这搞得太复杂了,我只是想在公司内部做各个管理系统的单点登录而已。好在还是有比较简单的方法的,就是发送 P3P 相关的 HTTP header。
ASP.NET:HttpContext.Current.Response.AddHeader("p3p", "CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
PHP:header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
JSP:response.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT'");
欢迎转载!但请带上文章地址^^