默认情况下,Mac上的Safari将Block cookies
设置为From third parties and advertisers
。
如果嵌入的swf来自不同的域,它会阻止SharedObject工作。
这个问题不是新问题: Safari 3rd party cookie iframe trick no longer working?
有没有人找到解决方案(除了在每个请求中通过GET / POST参数传递会话ID)?
注意: 我无法访问嵌入swf的网站,因此无法更改HTML或放置任何JavaScript等。
答案 0 :(得分:12)
function setCookie(){
if ( navigator.userAgent.indexOf('Safari') != -1 &&
navigator.userAgent.indexOf('Chrome') == -1 ){
window.open('safari.php','','width=200,height=100' );
}
}
// then we set the cookie in safari.php
来源:http://www.reizbombardement.de/archives/safari-5-1-4-enforces-cookie-policy
// 2013年7月23日更新
解决这个问题的这种糟糕的方法以前一直工作到Safari 6。
请参阅下面的@Fabio Antunes和@ncubica评论。
// Fabio Antunes 2013年7月23日更新
这是我的代码
在着陆页上,我们会对应用程序进行简要介绍,并提供一个类似“输入”的按钮。我正在使用jquery来简化这个过程,为click事件创建一个监听器,我只是放了javascript代码,因为我假设你已经拥有了登陆页面的其余html代码:
$(document).on("click", "#bt-landing", function(){
var left = (screen.width/2)-(500/2);
var top = (screen.height/2)-(250/2);
window.open('URL_FOR_THE_PHP_THAT_WILL_CREATE_THE_SESSION', '_blank', 'width=500,height=250,toolbar=0,location=0,menubar=0, top='+top+', left='+left);
});
这将打开一个500 x 250像素的小窗口,以屏幕为中心。
我对小窗口的代码是:
<?php setcookie("safari_cookie", "1");?>
<html>
<head>
<meta charset="utf-8">
<title>THE NAME OF YOUR APP OR SOMETHING THAT THE USER WE'LL READ AND ASSUME THAT THIS SMALL WINDOW IS RELIABLE</title>
</head>
<body>
<script type="text/javascript">
$(document).ready(function(){
setTimeout(function(){window.close()},1000);
})
</script>
</body>
</html
答案 1 :(得分:10)
Safari 仍会阻止来自顶级窗口中未访问过的域的Cookie 。
要解决此问题,我们会在PHP中计算($ _ COOKIES)并将浏览器定向到我们域上的页面,该页面的作用就是将浏览器发送回原来的位置。这是一个肮脏的伎俩,这意味着一些用户将不必要地被移走然后回来,但随后,网络充满了肮脏的技巧。
如果您无法将top.location.href
设置为域中需要设置Cookie的页面,或者您无法更改所述域上的页面,那么我可以自信地说您需要使用基于URL的会话。
但是,另一个选项(仍然需要能够在域上创建页面)是请求用户单击您的SWF,然后您可以触发window.open
并让URL指向该页面你创造了。它需要做的就是成功加载,然后用户(甚至弹出页面本身的JS)可以关闭弹出窗口。然后,您可以设置cookie。
我开发的Facebook应用程序存在于iframe中,这会遇到这个问题。每个应用程序都必须附带此修复程序。
答案 2 :(得分:1)
我可以从最近的经验中说,这不是Mac上Safari的问题,也不是我曾经遇到的问题。
您提到该设置阻止来自第三方的Cookie:SharedObject存储永远不会来自第三方,它来自您正在访问的网站(第一方?)。所以我认为这不会成为一个问题。
使用Flash Player设置面板,用户可以禁用SharedObject
(或限制存储空间量)。因此,通常,您的应用应该处理SharedObject
不可用的情况。
但是,我认为大多数用户都不知道SharedObject
并且他们可以禁用它。
答案 3 :(得分:1)
您可能需要使用跨域策略文件才能使swf正常工作。
答案 4 :(得分:1)
我已经用这种方式解决了,但最好使用HTML5 localstorage并使web服务更加安静,因为在server2中保存会话变量会使您的应用程序不能很好地扩展。 这里我用来解决第三方cookie问题的代码。基本上,server1的客户首先进入server2以获取“硬币:D”然后他突然回到server1。以这种方式,server2的会话变量在所有导航中都是可用的。 www.yourserver.com/index.html页面
<script src="js/jquery.cookie.js" type="text/javascript"></script>
<script src="js/mobile-detect.js" type="text/javascript"></script>
<script>
var md = new MobileDetect(window.navigator.userAgent);
if (md.userAgent()=='Safari') {
var firstsafariuser = $.cookie('safari-user');
if (firstsafariuser != 'true') {
$.cookie('safari-user', true);
location.href='http://www.yourserver2.com/coin.php?frompage='
+location.href.replace(location.hash,"")+'&hashtags='+location.hash.substr(1);
}
}
</script>
www.yourserver2.com/coin.php
<?php
session_start();
if (isset($_GET["frompage"])&&$_GET["frompage"]!=null){
$url=$_GET["frompage"];
} else {
$url='http://www.yourserver.com';
}
if (isset($_GET["hashtags"])&&$_GET["hashtags"]!=null){
$hash='#'.$_GET["hashtags"];
} else {
$hash='';
}
header('Location:'.$url.$hash);
?>
P.S。 window.open被视为一种弹出窗口,因此您可能会遇到广告拦截器或浏览器设置问题。
答案 5 :(得分:0)
只是为safari.xxx页面添加一个没有setTimeout和/或jquery的更干净的方法。适用于最新的ios(8.1.2),我知道8.1.0有一个窗口/标签不会关闭的错误。
以下是代码:
<%
request.getSession(true); //or anyway to set the cookie depending on your language (jsp here)
%>
<script type="text/javascript">
window.addEventListener("load", window.close);
</script>
弹出窗口在我的情况下不是问题,因为它是由用户点击启动的。