Facebook 如何在画布页面上为 iFrame 设置跨域 cookie?
Posted
技术标签:
【中文标题】Facebook 如何在画布页面上为 iFrame 设置跨域 cookie?【英文标题】:How does Facebook set cross-domain cookies for iFrames on canvas pages? 【发布时间】:2011-06-09 18:30:10 【问题描述】:我在浏览 Facebook 的有关画布应用程序的文档时遇到了一个示例应用程序:http://developers.facebook.com/docs/samples/canvas。然而,当我阅读他们的示例时,我对他们在 iframe 应用程序中使用 cookie 感到非常困惑。
一些背景故事......
我已经尝试过将 iframe 用于可嵌入小部件(与 Facebook 无关),并且我发现一些浏览器(Chrome、Safari 等)具有严格的 cookie 策略并且不允许在 iframe 中设置跨域 cookie (另一方面,Firefox 允许 iframe 在 iframe 中设置跨域 cookie)。例如,如果 foo.com 有一个带有 src="http://bar.com/widget"
的 iframe,则 iframe 小部件将无法为 bar.com 设置任何 cookie,因此将无法在 iframe 中持久化状态:bar.com 将解释每个请求(包括 ajax请求)作为没有建立会话的新请求来自小部件。我苦苦挣扎,通过使用 JSONP 和 javascript 为 foo.com 设置 cookie 找到了解决方法...
...等等?
好吧,我正在查看示例画布 iframe Facebook 应用程序,我注意到他们的应用程序(托管在 runwithfriends.appspot.com 上)能够设置一个 cookie,u
,带有当前用户的 ID 以及一些runwithfriends.appspot.com 域的其他参数。它会随每个请求发送此 cookie……它适用于 Chrome 和 Firefox!怎么回事? Facebook 如何绕过 Chrome 的跨域 cookie 限制?
(我现在已经知道答案了,但我认为这可能对任何想弄清楚同样事情的人有所帮助——我将在下面发布答案。)
【问题讨论】:
更新:某些浏览器的最新版本(OS X 上的 Safari v6.x+,ios 6+ 上的 Safari,我认为 Chrome 和 FF 很快)不再允许设置跨域 cookie ,即使在 post-to-iframe 请求上也是如此。 【参考方案1】:所以 iFrame 实际上并没有为 runwithfriends.appspot.com 域设置 u
cookie。 Facebook 所做的是创建一个表单 <form action="runwithfriends.appspot.com/..." target="name_of_iframe" method="POST">
并使用 javascript 在页面加载时提交表单。由于表单的目标是 iframe,它不会重新加载页面......它只是加载带有 POST 响应的 iframe。显然,即使是 Chrome 和其他具有严格 cookie 策略的浏览器也会为跨域请求设置 cookie,如果它们是 POST 请求...
【讨论】:
我创建了一个概念验证 sinatra 应用程序来演示其工作原理:github.com/agibralter/iframe-widget-test @LShetty -- 抱歉,我不确定我理解你的意思……纯 Javascript?演示的 Ruby 部分充当 Web 服务器...您的意思是要查看用 Node.js 编写的演示吗? @Seth 我有一段时间没检查了,但是最新版本的 Safari(v6.0/iOS6,我想很快 Chrome 和 FF)不再允许这个技巧了:cookie 不'不要设置 post-to-iframe 请求。我必须研究 Facebook 如何为新浏览器处理这个问题。目前,localStorage 似乎是一个不错的替代方法。 那么今天有没有办法设置 3rd 方 cookie,当它在浏览器中设置为阻止 3rd 方 cookie 时?或者有人可以验证今天以任何方式不可能吗? 大声笑,这些 cmets 实际上确实解释了很多关于 Web 浏览器 cookie 随着时间的演变......以上是关于Facebook 如何在画布页面上为 iFrame 设置跨域 cookie?的主要内容,如果未能解决你的问题,请参考以下文章
如何识别网页是在 iframe 中加载还是直接加载到浏览器窗口中?
如何识别网页是在 iframe 中加载还是直接加载到浏览器窗口中?