先看一個例子比如:我們在 www.cr173.com 中用 iframe 了一個 www.fxxz.com 的一個頁面。
如:
< iframe height="100" marginheight="0" src="http://www.fxxz.com/" frameborder="0" width="970" marginwidth="0" scrolling="no" bordercolor="#000000">< /iframe>
在IE下面 www.fxxz.com 這個被框住的頁面是無法進行COOKIE的讀寫的。
用 document.cookie; 是讀取不到 Cookie值的。
cookie的作用域又是如何界定的呢?
我在一個文件夾下,比如 d: mp\ 下建了幾個html文件,我發現在a.htm中創建的cookie,在b.htm中是可以識別的。 是不是可以認為,只要是同一個文件夾下的html文件,就可以共享cookie, 當然,我是在本機上做測試,如果作為一個網站來講,cookie的作用域又是如何界定的呢?
document.cookie = "username=" + escape(value)+ "; xpires ="+ expiration.toGMTString()+";path=/;domain=localhost; secure"; 就是說.當你PATH設置成/時.你當前文件夾或者DOMAIN下的所有子文件及子文件夾里的文件都可以讀到.但當設置為/thispathname就只有DOMAIN/thispathname下的文件及文件夾能讀寫。
其根源也是由於iframe跨站點cookie被阻導致session失效。但是當時因為兩個站點都是自有的服務器,因此通過設置了相同的父域名解決了此問題,所以后來也就沒有深入研究此問題。
目前在開發新功能時,又一次遇到了此問題,但是如果仍舊通過更改域名的方式來解決的話,設計上可能就會非常麻煩。於是不得已徹底翻了一下資料,初步研究結果如下:
問題根源: IE6/IE7支持的P3P(Platform for Privacy Preferences Project (P3P) specification)協議默認阻止第三方無隱私安全聲明的cookie,Firefox目前還不支持P3P安全特性,firefox中自然也不存在此問題了。Mircosoft對此的具體描述可以參見 Privacy in Internet Explorer 6 解決方法: 很簡單,在要嵌入的內容中(iframe指向的站點)輸出P3P的主機頭聲明,步驟如下 (Session variables are lost if you use FRAMESET in Internet Explorer 6):
1.打開IIS管理器 inetmgr 2.選擇被嵌入iframe源站點或者目錄,右鍵點擊打開屬性框 3.切換到HTTP頭 4.添加
5.自定義HTTP頭名: P3P 6.自定義HTTP頭值: CP="CAO PSA OUR"
7.關閉屬性框退出,即刻生效
我們可以查一下 HTTP 頭信息
http://tool.chinaz.com/pagestatus/
用這里可以查看一下剛剛的設置:
至於上面CAO PSA OUR的具體意思,還是請參考前面的文章:Privacy in Internet Explorer 6
如果是動態語言可以用下面的添加頭信息的辦法來解決:
PHP
<?php header('P3P: CP="CAO PSA OUR"');//ADD IN THIS LINE IN ORDER TO SOLVE THE INTERNET EXPLORER ALWAYS GET NEW SESSION ISSUEsession_start();$_SESSION['test']='anything';echo$_SESSION['test'];
?>
關於“用P3P header解決iframe跨域訪問cookie/session”的問題
理論很簡單,而且模式也和大多請求返回狀態的SSO差不多.但是有幾個地方是要注意一下的. 1.頁面里的COOKIE不能是瀏覽器進程的COOKIE(包括驗證票和不設置超時時間的COOKIE),否則跨域會取不到.這點做跨域COOKIE的人比較少提到.不過實際上留意下幾家大學做的方案,有細微的提到他們的驗證模塊里的COOKIE是有設置超時時間的. 2.當利用IFRAME時,記得要在相應的動態頁的頁頭添加一下P3P的信息,否則IE會自覺的把IFRAME框里的COOKIE給阻止掉,產生問題.本身不保存自然就取不到了.這個其實是FRAMESET和COOKIE的問題,用FRAME或者IFRAME都會遇到. 3.測試時輸出TRACE,會減少很多測試的工作量. 只需要設置 P3P HTTP Header,在隱含 iframe 里面跨域設置 cookie 就可以成功。他們所用的內容是: P3P: CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'
ASP直接在頭部加了頭部申明,測試有效
<%Response.AddHeader "P3P", "CP=CAO PSA OUR"%> php的話,我沒去試,應該是如下寫法: header('P3P: CP=CAO PSA OUR');
ASP.NET的話
通過在代碼上加Response.AddHeader("P3P", "CP=CAO PSA OUR") 或者在Window服務中將ASP.NET State Service 啟動。
JSP: response.setHeader("P3P","CP=CAO PSA OUR")