在Safari中设置跨域Cookie
Evernote的小书签能够做到这一点,因此即使赏金会以非生产性的方式进行,最高的答案也不会回答这个问题。
我必须从B.com域调用域名A.com(它用cookie设置cookie)。 我所做的域名B.com是(JavaScript):
var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.src = "A.com/setCookie?cache=1231213123"; head.appendChild(script);
这会在我testing的每个浏览器上设置A.com上的Cookie,但Safari除外。 令人惊讶的是,即使没有P3P头文件,也可以在IE6中使用。
有没有什么办法可以使这个工作在Safari?
从Safari Developer FAQ
:
Safari提供了一个保守的Cookie策略,它将cookie写入限制为仅由用户select的页面(“导航到”)。 这种默认的保守策略可能会混淆尝试写入cookie并失败的基于框架的站点。
我找不到解决这个问题的办法。
如果有任何价值,如果您使用<script
>追加方法,则Chrome不会设置Cookie,但是如果您使用相同来源的隐藏<img
>,Chrome除了其他浏览器(除了“再次,Safari)
2014-2016工作方法:
你必须做的window.open到域/分配一个cookie /closurespopup窗口,该域名现在是安全列表。
原来的post@ PHP多个cookies不能在iPad / iPhone浏览器上工作
假设他们已经安装了Flash,有一个坏习惯。
我不确定它是否仍然有效,但Flash'es“本地共享对象”又名Flash Cookies可以帮助您环绕Safari的同域策略。
本地共享对象教程
但是,至less可以说实施起来可能很复杂。
- 维基百科有关LSO的文章
另外,LSO正在作为一个安全噩梦进入光明:
- LSO电子隐私信息中心
- Flash Cookies:无声的隐私杀手
所以在使用之前请仔细考虑。
发布到隐藏的<iframe>
可以允许您在Safari中绕过此限制 – http://gist.github.com/586182 :
<?php header('P3P: CP=HONK'); setcookie('test_cookie', '1', 0, '/'); ?> <div id="test_cookie" style="position: absolute; top: -10000px"></div> <script> window.setTimeout(function() { if (document.cookie.indexOf('test_cookie=1') < 0) { var name = 'test_cookie', div = document.getElementById(name), iframe = document.createElement('iframe'), form = document.createElement('form'); iframe.name = name; iframe.src = 'javascript:false'; div.appendChild(iframe); form.action = location.toString(); form.method = 'POST'; form.target = name; div.appendChild(form); form.submit(); } }, 10); </script>
2015年的工作有一个适当的解决方法。假设有网站y.com,其中包括与网站x.com的iframe。 x.com iframe想要存储一个cookie。 这是Safari政策所不允许的,但是,y.com能够存储它。 所以y.com必须收听来自x.com的消息,然后存储cookie本身。
var _cookieEvMth = window.addEventListener ? "addEventListener" : "attachEvent"; var _cookieEvAction = window[_cookieEvMth]; var _cookieEv = _cookieEvMth == "attachEvent" ? "onmessage" : "message"; _cookieEvAction(_cookieEv, function(evt){ if(evt.data.indexOf('cookieset')!=-1){ var datack = evt.data.split('|'); YOUR_CUSTOM_COOKIE_SAVE_METHOD(datack[1],datack[2],datack[3]); } },false);
当x.com需要存储cookie时,它必须发送消息给y.com:
window.parent.postMessage('cookieset|'+ckName+'|'+ckVal+'|'+days,'*');
如果你想读取cookie,你也可以用自己的方式发送消息到iframe。 或者,您可以使用javascript将它作为参数包含在x.com iframe url中:
iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));
我们在工作中提出的解决方法是通过一个window.open()来设置cookie – 它可能不是最优的(因为你会有一个丑陋的屁股popup窗口打开),但它对我们很好。 我们不得不打开一个popup窗口来进行OAuth身份validation。
所以我们所做的是:
- 用户点击B.com的链接
- popup窗口打开到A.com/setCookie
- A.com设置它的cookie,然后在适当的地方redirect到B.com
再一次,在所有的解决scheme中都不是有效的,但它在我们的工作。 希望这可以帮助。
我知道这个问题是相当古老的,但这帮助我解决了cookies问题:
var cookieForm = document.createElement("form"); cookieForm.action = "A.com/setCookie?cache=1231213123"; cookieForm.method = "post"; document.body.appendChild(cookieForm); cookieForm.submit();
在设置您的Cookie的页面上发布表单的想法。
* 编辑 *这种解决方法已被报告在WebKit中closures。
卢卡,
好的,所以这个答案是两年前,但是…你可以从一个iframe设置一个cookie,如果你张贴表单到一个隐藏的iframe。 你可以通过创build一个表单来做到这一点:
<form id="myiframe" action="http://yourdomain.com" method="POST" target="iframe_target">
然后在Javascript中,获取表单的参考和调用提交:
document.getElementsByTagName('form')[0].submit();
你可以听取iframe的onload,或者你可以让你的iframe动作页面发出一些JavaScript信号的负载。 我已经在Safari和Chrome中testing过了,它工作。
干杯。
也许实际上创build并点击一个带有href="A.com/setCookie?cache=1231213123"
的链接,并指向一个隐藏的iframe的目标属性。 这可能会绕过Safari的用户导航设置cookie的政策(我没有Safari方便testing。)
当我尝试部署使用Windows Live ID的网站时,我对此进行了广泛的调查,该网站依靠能够设置第三方cookie来注销的能力。 它只是…没有工作。 没有什么可以做到的, Live ID团队也进行了广泛的调查,他们的回答是“无法工作”。
注意这一行:
script.src = "A.com/setCookie?cache=1231213123";
我无法得到这个工作,直到我join了http,即
script.src = "http://A.com/setCookie?cache=1231213123";
我find一个简单的解决scheme 你只需要第一次设置cookie来检查请求是否来自同一个来源,如果不是像往常一样,你需要返回到iframe脚本,将重复这个请求,已经有权限分配cookie。 之后,您可以直接通过访问此cookie的iframe来完成其他请求。 这在我的跟踪系统中帮助了我。 试试,这个效果很好。
尝试像这样:
var w = window.open("A.com/setCookie?cache=1231213123"); w.close();
它可能会绕过狩猎的安全政策。
这不是缺less的types – 属性这是烦你吗?)
<script type="text/javascript"> var head = document.getElementsByTagName("head")[0]; var script = document.createElement("script"); script.setAttribute("type","text/javascript"); script.src = "A.com/setCookie?cache=1231213123"; head.appendChild(script); </script>