设定交叉领域在野生动物饼干
-
03-07-2019 - |
题
笔记's书签是能够做到这一点,因此大多数投赞成票的答复没有回答这即使赏金将转到它(非生产性的方式)。
我要呼叫域A.com (其中规定的饼干http)自域B.com.所有我做域B.com 是(javascript):
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = "A.com/setCookie?cache=1231213123";
head.appendChild(script);
这套上cookie A.com 在每一浏览器,我已经测试,除了野生动物园。令人惊讶的是这种工作在IE6,即使没有P3P头。
是否有任何方式使这项工作在野生动物园?
解决方案
来自 Safari Developer FAQ
:
Safari附带了一个保守的cookie策略,该策略将cookie限制仅限于用户选择的页面(<!>“导航到<!>”;)。此默认保守策略可能会混淆尝试写入cookie并失败的基于帧的站点。
我发现无法解决这个问题。
如果它有价值,那么如果您使用<script
<!> gt,则Chrome不会设置Cookie;附加方法,但如果你有一个隐藏的<img
<!> gt;使用相同的来源,除了其他浏览器(除了Safari)之外,Chrome还可以使用
其他提示
这是一个有效的解决方案:
2014 - 2016年工作方法:
你必须对window.open进行域名/分配cookie /关闭弹出窗口,域名现在已经过安全列表。
有一点的一个邪恶的伎俩,假设他们有闪光灯的安装。
我不知道,如果它仍然有效或者没有,但Flash'es"本地共享的对象"aka 闪饼干 可以帮你环游Safari是相同的-域的政策。
然而,它可能是复杂的实施,至少可以这样说。
此外、莱索托的是即将进入光作为一个安全的噩梦:
所以仔细想想之前使用它们。
隐藏<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网址中iframe.setAttribute('url','x.com/?cookieval='+YOUR_COOKIE_GET_METHOD('cookiename'));
我们刚刚在我的工作中提出的解决方法是通过window.open()设置cookie - 它可能不适合你(因为你将打开一个丑陋的屁股弹出窗口),但它有效对我们好我们必须打开一个弹出窗口进行OAuth身份验证。
所以我们所做的就是:
- 用户点击B.com的链接
- 弹出窗口将打开A.com/setCookie
- A.com设置其cookie,然后在适当的位置重定向到B.com 醇>
同样,在所有解决方案中都无效,但它在我们的解决方案中有效。希望这会有所帮助。
我知道这个问题相当陈旧,但这有助于我解决Cookie问题:
var cookieForm = document.createElement("form");
cookieForm.action = "A.com/setCookie?cache=1231213123";
cookieForm.method = "post";
document.body.appendChild(cookieForm);
cookieForm.submit();
在设置Cookie的网页上发布表单的想法。
*的 修改 * 强> 据报道,此解决方法已在WebKit中关闭。
卢卡,
好的,所以这个答案已经有两年了,但是......如果你把一个表格发布到一个隐藏的iframe,你可以从iframe设置一个cookie。您可以通过创建表单来完成此操作:
<form id="myiframe" action="http://yourdomain.com" method="POST" target="iframe_target">
然后在Javascript中,获取对表单的引用并调用submit:
document.getElementsByTagName('form')[0].submit();
您可以收听iframe的onload,也可以让iframe操作页面发出一些指示负载的javascript。我已经在Safari和Chrome中对此进行了测试,但它确实有效。
干杯。
这可能对每个人都不起作用,但我遇到了这个问题,因为我从不同于API的主机提供React应用程序,最终有效的解决方案是使用DNS:
我们的客户来自www.company-name.com,我们的API位于company-name.herokuapp.com。通过制作 CNAME 记录api.company-name.com - <!> gt; company-name.herokuapp.com,让我们的客户使用该子域进行API调用,Safari停止将其视为<!>“第三方<!>”; cookie中。
好处是所涉及的代码非常少,并且它都使用了成熟的东西...缺点是如果你要使用https,你需要对API主机有一些控制/所有权 - 他们需要一个对客户端域有效的证书,或者用户将获得证书警告 - 因此如果所涉及的API不是您的或合作伙伴的话,这将无效(至少不适用于面向最终用户的内容)。
也许实际创建并单击带有href="A.com/setCookie?cache=1231213123"
和目标属性的链接指向隐藏的iframe。 可能绕过Safari的用户导航政策来设置Cookie(我没有Safari方便测试。)
当我尝试部署使用Windows Live ID的网站时,我对此进行了一些广泛的调查,这取决于是否能够设置第三方Cookie以便注销。它只是......没有用。我们所做的一切都无法让它发挥作用。 Live ID团队也进行了广泛的调查,答案是<!>“无法使其工作<!>”。
请注意以下这一行:
script.src = "A.com/setCookie?cache=1231213123";
直到我添加了http,即
,我才能解决这个问题script.src = "http://A.com/setCookie?cache=1231213123";
我找到了一个简单的解决方案。您只需要第一次设置cookie来检查请求是否来自同一来源,如果不像往常一样,您需要返回iframe一个将重复此请求的脚本,已经拥有分配cookie的权限。之后,您可以直接通过iframe访问此cookie来执行其他请求。这有助于我的跟踪系统。试试,这很有效。
值得注意的是,Safari中的此限制不适用于子域。因此,如果您直接访问sitea.com,则可以在没有直接用户交互(iframe / JavaScript)的情况下从subdomain.sitea.com设置cookie。
这与我开发API时的情况相关。如果您的访问者到达mysite.com,然后您想要一些JavaScript与您的API进行交互,那么如果API在api.mysite.com上托管,那么它将适用于Safari。
将此JavaScript放在发出跨域请求的页面上, http://example1.com/index.html :
<script>
var gup = function(name, url) {
if(!url) url = location.href;
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( url );
return results == null ? null : results[1];
}
var isSafari = navigator.vendor && navigator.vendor.indexOf('Apple') > -1 && navigator.userAgent && !navigator.userAgent.match('CriOS');
var n = gup("activated");
if(isSafari && n == null) {
//browser is Safari and cookies have not yet been activated
var current_url = location.protocol + '//' + location.host + location.pathname;
var query_string = '?callback=' + encodeURIComponent(current_url + '?activated=1');
var new_url = 'http://example2.com/activate.php' + query_string;
window.location.href = new_url;
}
//the rest of your code goes here, and you can now set cross-domain cookies on Safari
</script>
然后在另一台需要设置cookie的服务器上创建一个文件, http://example2.com/ activate.php :
<?php
if(isset($_GET['callback'])) {
header('Location: '.$_GET['callback']);
exit();
} else {
//in case callback param is not set, simply go back to previous page
echo "<script>";
echo "window.history.back();";
echo "</script>";
exit();
}
?>
以下是其工作原理:
-
首次访问 http://example1.com/index.html 时,检查浏览器是否为Safari以及名称<!>的GET参数是否激活<!>“;不存在。如果满足这两个条件(这将在首次访问Safari浏览器时发生),则浏览器将重定向到 http ://example2.com/activate.php ,带有GET参数,<!> quot; callback <!> quot;,其中包含附加了<!>“;激活<!>”的调用URL;参数。
-
http://example2.com/activate.php 只是重定向回到GET参数中包含的URL,<!> quot; callback <!> quot;。
-
http://example1.index.html 现在第二次被点击后重定向到,GET参数,<!>“;激活<!>”;现在将被设置,因此步骤1中的条件将不会执行,从而允许脚本继续执行。
醇>
这满足了Safari要求浏览器至少访问第三方域名以便开始设置cookie的要求。
尝试类似:
var w = window.open("A.com/setCookie?cache=1231213123");
w.close();
它可能会绕过safari的安全政策。
这不是缺少类型属性让你烦恼吗? - )
<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>