【发布时间】:2013-10-26 14:15:51
【问题描述】:
我有一个 facebook Iframe 应用程序,其中包含多个 PHP 页面。
我有一些链接指向我的“iframe 文件夹”中的文件。
iframe 中的会话变量存在一些问题。我设置了一些会话变量,但它们不会从一个页面持续到另一个页面。
这确实适用于其他浏览器。
我一直在阅读 Safari 不支持跨域 cookie,这可能是问题所在,但我不确定如何解决。
有什么帮助吗?
【问题讨论】:
我有一个 facebook Iframe 应用程序,其中包含多个 PHP 页面。
我有一些链接指向我的“iframe 文件夹”中的文件。
iframe 中的会话变量存在一些问题。我设置了一些会话变量,但它们不会从一个页面持续到另一个页面。
这确实适用于其他浏览器。
我一直在阅读 Safari 不支持跨域 cookie,这可能是问题所在,但我不确定如何解决。
有什么帮助吗?
【问题讨论】:
我相信这个解决方案在 Safari 的最新(6.0 和更高版本)版本中已经过时了。
默认情况下,Safari 不允许从第三方设置 cookie。这会影响 Facebook iframe 应用程序,因为用户正在访问从 apps.facebook.com 提供的页面,但 iframe 是从 yourdomain.com(在这种情况下为“第三方”)提供的。
网络上提到了几种解决方案。 Facebook 在其miscellaneous issues 列表中发现并推荐的最好方法是使用 JQuery 伪造对yourdomain.com 的 POST 请求。 Anant Garg 详细介绍的此解决方案通常适用于不同的主机/iframe 域,并且需要针对 Facebook 应用程序进行调整。关键部分是:
$("body").append('
<iframe id="sessionframe" name="sessionframe" onload="submitSessionForm()" src="http://www.yourdomain.com/blank.php" style="display:none;"></iframe>
<form id="sessionform" enctype="application/x-www-form-urlencoded"
action="http://www.yourdomain.com/startsession.php"
target="sessionframe" method="post"></form>');
var firstTimeSession = 0;
function submitSessionForm() {
if (firstTimeSession == 0) {
firstTimeSession = 1;
$("#sessionform").submit();
}
}
Will Henderson 的另一个解决方案是使用 Javascript 函数为页面上的每个链接提供会话信息。然后修改您的服务器代码以通过从 GET 参数中读取此会话信息来捕获它。
【讨论】:
我写了the blog postDominic 在他的回答中提到。
问题在于 Safari 的默认行为是只接受来自您访问的网站的 cookie。这不包括“第三方”cookies。 Safari 将 IFRAME 内的页面视为第三方网站,并且在您与该内容进行交互(例如通过单击链接)之前,它会拒绝这些 cookie。
您的 PHP 代码需要在使用会话的第一页上设置一个 cookie,以便该会话从一个页面持续到另一个页面,但如果会话变量位于 IFRAME 的第一页中,则您有一个鸡和蛋的问题。
我的解决方案是保留所有特殊的 Facebook 参数,直到加载到 IFRAME 的第二个页面。因为您已经与之交互,所以设置在第二页上的 cookie 将保持不变,这允许您的 PHP 代码保持与 Facebook 通信所需的任何状态。
不过,这可能对您的 PHP 会话没有帮助,因此我建议在第一页上的链接中添加另一个参数,以允许第二页查找会话,或者以其他方式重新创建它。
【讨论】:
我认为最好的解决方案是手动跟踪会话 ID,即使用 session_id($_GET['session]); 只需确保在调用 session_start(); 之前执行此操作,一切正常。
【讨论】:
Safari 仅接受来自用户导航到的页面的 cookie。解决此问题的最简单和最有效的方法是使用 top.location.href 将请求从画布应用程序的登录页面重定向到域上的不同页面,并将用户从该页面重定向回画布应用程序。
例如,如果 abc.php 是您的登录页面,并且画布 URL 是 facebook.com/abc。首先将请求从 abc.php 重定向到不同的页面,例如 xyz.php,然后再次从 xyz.php 重定向到 facebook.com/abc。不要忘记在 xyz.php 中启动会话。
这是一个简单的修复...
【讨论】:
感谢您的所有意见。我最终通过在每个页面上附加“signed_request”参数来解决问题。我只是将其作为隐藏字段放入并设置在后面的代码中。这样我就设法让它在 Safari 中工作。希望它也对你有用。
【讨论】:
随着 Safari 7 的发布,不仅 3rd Party cookie 被阻止。本地存储以及 WebDB,任何类型的网站数据都被阻止。当您转到 Safari 首选项(CMD+逗号)时,在 Safari 7 上的隐私选项卡下,现在显示:“阻止 cookie 和其他网站”,原来是“阻止 cookie”。这证实了这些变化。
其他浏览器将来可能会跟进。最有可能是火狐。 Chrome,咳 *咳*可能不会。
您可能必须使用重定向技术或类似于 disqus 所做的弹出窗口的一些变通方法。
【讨论】:
如果您使用 .NET,那么这个问题有一个更简单的解决方案。
只需在 web.config 中将 cookieless 设置为 false。例如:
sessionState mode="InProc" cookieless="true" timeout="60"
这比发布 iframe 或使用 iframe 的 url 打开弹出窗口要容易得多。
亲切的问候,
大卫
【讨论】:
我在 PHP 中使用了这个标头,解决了我的问题
if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') ) header('P3P:CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
【讨论】: