我想调查facebook登录如何将数据传输到主页面(mypage) - 尽管存在跨域限制。
所以我创建了一个包含FB js sdk
代码的新页面:
FB.login(function (response)
{
if (response.authResponse)
{...
它会打开弹出窗口:
但是当我调查我的网页上是否有任何iframe 时(我的代码中不包含任何iframe):
我看到了这个:
>>$("iframe")
结果:
[
<iframe name="fb_xdm_frame_http" frameborder="0" allowtransparency="true" scrolling="no" id="fb_xdm_frame_http" aria-hidden="true" title="Facebook Cross Domain Communication Frame" tab-index="-1" src="http://static.ak.facebook.com/connect/xd_arbiter.php?version=24#channe…l_path=%2FWebSite2%2FHTMLPage3.htm%3Ffb_xd_fragment%23xd_sig%3Df5252874%26" style="border: none;">…</iframe>
,
<iframe name="fb_xdm_frame_https" frameborder="0" allowtransparency="true" scrolling="no" id="fb_xdm_frame_https" aria-hidden="true" title="Facebook Cross Domain Communication Frame" tab-index="-1" src="https://s-static.ak.facebook.com/connect/xd_arbiter.php?version=24#cha…l_path=%2FWebSite2%2FHTMLPage3.htm%3Ffb_xd_fragment%23xd_sig%3Df5252874%26" style="border: none;">…</iframe>
]
我读到它们用于跨域。
但问题是他们为什么在我的页面上?
他们应该在Facebook内部页面的某个地方!
我说的是因为我知道 iframe技术的工作原理如下:
正如您所看到的 - 内部Iframe使用查询字符串中的SRC
值创建另一个 iframe(该值实际上是首页网址),然后使用JS页面+ URL => JS
触发函数,我们可以这样做:
top.sendData({...})
我错过了什么?
答案 0 :(得分:33)
我是在Facebook JS SDK中为跨域消息传递设计当前基础架构的工程师,所以也许我可以在这里阐述一些事情。
这种设置可能看起来有点不正统,有些人会感到困惑,但如果我自己也这样说的话,它真的非常优雅:)
根据页面是HTTP还是HTTPS,JS SDK将创建两个iframe,指向xd_arbiter.php资源,该资源由* .facebook.com域提供。由于它设置了document.domain = 'facebook.com'
,因此可以与facebook.com上的其他资源进行通信。
这些资源(代理)通过片段传递一些信息,为它们提供动态功能,但是否则100%是静态的并且由浏览器缓存 - 因此加载速度非常快。
接下来发生的是在主机页面和每个iframe(代理服务器)之间建立跨域消息传递链接。这意味着从现在开始,主页可以与facebook.com上的HTTPS页面进行通信,如果主页是HTTP,它还可以与facebook.com上的HTTP页面进行通信。
此链接如何在浏览器中运行是一个更复杂的问题,但它全部被抽象为一个频道,就像您在easyXDM看到的那样。
现在,只要JS SDK在facebook.com上创建一个新窗口,无论是作为弹出窗口还是作为iframe,而不必在主机页面和每个窗口之间建立新的通信通道,新的窗口可以利用现有代理,在设置中不需要任何费用。
当需要向主机页面发送消息时,这些消息将使用(window.opener || window.parent).frames['fb_xdm_frame_' + location.protocol.replace(':', '')
来获取代理的句柄,同样,代理可以使用parent.frames[some_name]
来获取任何兄弟iframe的句柄该页面,只要使用了正确的代理(HTTP或HTTPS)。
对我们来说,这基本上意味着关于如何跨域通信的关注与JS SDK及其资源是分离的 - 我们在此基础上构建的任何服务都可以依赖于send_this_message(message, origin)
的非常简单的api如果我们有原始支票允许,它将“神奇地”在另一端结束。
我希望这能回答你的问题!
(xd_arbiter.php也可以作为重定向目标,它将使用它的兄弟代理来中继消息)。
答案 1 :(得分:0)
我认为如果你的代码中有ie8 +,这个概念可以很简单。
CORS可用于跨域通信。确保在您的主机上设置了正确的标题,并且您很好。
或者,创建一个iframe,将其src设置为将信息传递给动态脚本的东西。处理信息。将JS代码返回到使用postMessage与外部窗口通信的iframe。