我相信这篇文章会很有用:
http://www.how2guru.com/archives/php-session-problem-while-using-iframe/
简短的回答是:在 iframe 中,像这样开始会话:
header('P3P: CP="CAO PSA OUR"');
session_start();
编辑:
我想我应该更新这个答案,因为我偶然发现了一些每个人都应该知道的有趣的事情。
此 p3p 标头 hack不适用于 safari。
下面我描述了我的登录流程,以及我是如何解决这个问题的。
我的登录流程如下所示(页面应用):
- 检查当前用户是否有会话,
- 如果没有,则重定向到登录网址(由 PHP SDK 生成),
- 登录对话框重定向回一个 url,我使用 'code' GET 参数 facebook 给我,获取访问令牌,我可以存储以供以后使用。 (保存到数据库和到会话。)如果我完成了,我将用户重定向到我的页面应用程序,一切都会工作。
- 此时每个人都应该感到高兴。
但是问题来了。
如果用户使用 safari,并在会话已被破坏时(例如几天后)尝试打开此应用,则会发生以下情况:
- 代码检查会话:它找到用户 ID(PHP SDK getUser() 方法),所以我首先检查数据库中的条目。
- 由于用户之前登录过,他在数据库中有一个条目,所以我只是抓取它并将其保存到会话中,这样以后的 AJAX 调用将拥有他们需要的所有信息。
这里要注意的重要一点是,此代码在 iframe 内的页面选项卡中运行。
因此对于大多数用户而言,由于 p3p 标头 hack,该代码将起作用。
但对于 safari 用户来说不会。
Safari 不关心给定的标头,它拒绝保存会话,因此用户登录到应用程序,一切似乎都工作正常,但 ajax 调用不起作用,因为它们没有任何可以使用的会话。
解决方法:
实际上很简单 - 虽然不是太优雅,但是嘿,它有效。 -:我检查客户端浏览器是否是 safari,如果是,我会重定向到自定义 url,在那里我开始一个会话 - 在 facebook iframe 之外 - 然后重定向回应用程序。
这将毫无问题地创建 cookie,因此会话将可用。
这里有一些代码:
-
检查会话
(Credit goes to this guy)
if (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') && !strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome')) {
if (count($_COOKIE) === 0) {
echo '<script>
top.location = "http://www.domain.com/setcookie.php";
</script>';
}
}
-
设置会话(setcookie.php)
header('P3P: CP="CAO PSA OUR"');
session_start();
$_SESSION = array();
echo
'<script>
top.location = "http://back-to-the-facebook-app.com";
</script>';
我希望这个额外的技巧对某人有所帮助。
EDIT2
我还没有尝试过这个,但是您可以在 .htaccess 中添加以下行,而不是添加 P3P 标头:
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
</IfModule>
使用 cmets:
# ------------------------------------------------------------------------------
# | Cookie setting from iframes |
# ------------------------------------------------------------------------------
# Allow cookies to be set from iframes in IE.
# http://msdn.microsoft.com/en-us/library/ms537343.aspx
# http://www.w3.org/TR/2000/CR-P3P-20001215/
<IfModule mod_headers.c>
Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""
</IfModule>
Yeoman 项目背后的人的所有功劳都归功于这个 .htacces 代码。