javascript 阻止第三方 cookie - 解决方法(facebook 应用程序等)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11635105/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
block third party cookies - workaround (facebook apps etc)
提问by sanchez
Safari on a Mac has a Block cookies
set to From third parties and advertisers
by default.
Mac 上的 Safari默认Block cookies
设置为From third parties and advertisers
。
It stops the SharedObject from working if the embedded swf is from a different domain.
如果嵌入的 swf 来自不同的域,它会阻止 SharedObject 工作。
This problem isn't new: Safari 3rd party cookie iframe trick no longer working?
这个问题并不新鲜: Safari 3rd party cookie iframe 技巧不再有效?
Has anyone found a solution (other then passing the Session ID through GET/POST params in each request)?
有没有人找到解决方案(然后在每个请求中通过 GET/POST 参数传递会话 ID)?
NOTE: I have no access to the site, which is embedding the swf, so there is no way to alter that HTML or to put any JavaScript, etc.
注意:我无法访问嵌入 swf 的站点,因此无法更改该 HTML 或放置任何 JavaScript 等。
回答by sanchez
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
Source: http://www.reizbombardement.de/archives/safari-5-1-4-enforces-cookie-policy
来源:http: //www.reizbombardement.de/archives/safari-5-1-4-enforces-cookie-policy
//UPDATE 23 July 2013
//2013 年 7 月 23 日更新
This crappy way of fixing this issue used to work until Safari 6.
这种解决这个问题的糟糕方法在 Safari 6 之前一直有效。
Please see @Fabio Antunes and @ncubica comments below.
请参阅下面的@Fabio Antunes 和@ncubica 评论。
//UPDATE 23 July 2013 by Fabio Antunes
//更新 2013 年 7 月 23 日法比奥·安图斯 (Fabio Antunes)
Here's my code
这是我的代码
On the landing page we'll have a brief description about the app and a button saying something like "enter". I'm using jquery to simplify this process, creating a listener for the click event, I'll just put the javascript code, since I'm assuming you already have the rest of the html code for the landing page:
在登陆页面上,我们将有一个关于应用程序的简短描述和一个类似“输入”的按钮。我正在使用 jquery 来简化这个过程,为点击事件创建一个侦听器,我将只放置 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);
});
This you'll open a small window, with 500 by 250 px, centered on your screen.
这将打开一个小窗口,大小为 500 x 250 像素,以屏幕为中心。
The code I have for the small window is this:
我的小窗口代码是这样的:
<?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
回答by rcambrj
Safari does still block cookies from domains which it has not visited in the top window.
Safari仍然会阻止来自它在顶部窗口中没有访问过的域的 cookie。
To workaround this, we count($_COOKIES) in PHP and direct the browser to a page on our domain whose job it is to simply send the browser back to where it came from. It's a dirty trick which means some users will unnecessarily get moved away and then back, but then, the web is full of dirty tricks.
为了解决这个问题,我们在 PHP 中 count($_COOKIES) 并将浏览器定向到我们域中的一个页面,该页面的工作是简单地将浏览器发送回它的来源。这是一个肮脏的把戏,这意味着一些用户会不必要地离开然后又回来,但是,网络充满了肮脏的把戏。
If you cannot set top.location.href
to a page on the domain which needs to set cookies, or you cannot alter a page on said domain, then I can confidently say you'll need to use URL-based sessions.
如果您无法设置top.location.href
需要设置 cookie 的域上的页面,或者您无法更改所述域上的页面,那么我可以自信地说您需要使用基于 URL 的会话。
However, an alternative option (which still requires being able to create a page on the domain) is to request that the user clicks on your SWF, you can then trigger window.open
and have the URL point to the page you created. All it needs to do is load successfully, then the user (or even JS on the popup page itself) can close the popup. You may then set cookies.
但是,另一种选择(仍然需要能够在域上创建页面)是请求用户单击您的 SWF,然后您可以触发window.open
并让 URL 指向您创建的页面。它需要做的就是成功加载,然后用户(甚至弹出页面本身的 JS)可以关闭弹出窗口。然后您可以设置 cookie。
I develop Facebook apps, which live inside iframes, which suffer this problem. Every single app has to be shipped with this fix.
我开发了位于 iframe 中的 Facebook 应用程序,但遇到了这个问题。每个应用程序都必须附带此修复程序。
回答by Hades
You may need to use a cross-domain policy file for the swf to work correctly.
您可能需要使用跨域策略文件才能使 swf 正常工作。
回答by Sunil D.
I can say from very recent experience that this is not a problem with Safari on a Mac, nor have I ever experienced it as a problem.
我可以根据最近的经验说,这不是 Mac 上 Safari 的问题,我也从未将其视为问题。
You mentioned the setting is blocking cookies from 3rd parties: SharedObject storage is never from a third party, it's from the site you're visiting (the 1st party?). So I don't think that will ever be an issue.
您提到设置阻止来自第 3 方的 cookie:SharedObject 存储永远不会来自第三方,而是来自您正在访问的站点(第一方?)。所以我认为这永远不会成为问题。
Using the Flash Player settings panel, the user can disable the SharedObject
(or limit the amount of storage space). So in general, your app should handle the case where the SharedObject
is not available.
使用 Flash Player 设置面板,用户可以禁用SharedObject
(或限制存储空间量)。所以一般来说,你的应用程序应该处理SharedObject
不可用的情况。
However, I think most users are not aware of the SharedObject
and that they can disable it.
但是,我认为大多数用户不知道SharedObject
并且他们可以禁用它。
回答by Marcello Kad
I've solved in this way, but it's better to use HTML5 localstorage and make webservices restful because holding session variables in server2 make your application not well scalable. Here the code i've used to solve the 3rd party cookie problem. Basically guests of server1 goes first to server2 in order to take "the coin :D" and suddenly he come back to server1. In this way session variables of server2 are avaliable in all navigation. www.yourserver.com/index.html page
我已经通过这种方式解决了,但最好使用 HTML5 localstorage 并使 webservices 安静,因为在 server2 中保存会话变量会使您的应用程序不能很好地扩展。这是我用来解决第 3 方 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
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 are seen like a kind of popup so you might have problem with ad-blockers or browser settings.
PS window.open 被视为一种弹出窗口,因此您可能会遇到广告拦截器或浏览器设置的问题。
回答by Kim D.
Just to add a cleaner way without setTimeout and or jquery for the safari.xxx page. Works fine with the latest ios (8.1.2), I know for 8.1.0 there was a bug where the window/tab wouldn't close.
只是为 safari.xxx 页面添加一种没有 setTimeout 和/或 jquery 的更简洁的方式。适用于最新的 ios (8.1.2),我知道 8.1.0 存在窗口/选项卡无法关闭的错误。
Here is the code:
这是代码:
<%
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>
The popup is not an issue in my case since it is initiated by a click from the user.
在我的情况下,弹出窗口不是问题,因为它是由用户单击启动的。