18

我想研究 facebook 登录如何将数据传输到主页( mypage )——尽管有跨域边界限制。

所以我用FB js sdk代码创建了一个新页面:

FB.login(function (response)
    {
    if (response.authResponse)
        {...

它确实打开了弹出窗口:

在此处输入图像描述

但是当我调查我的页面上是否有任何 iframe (我的代码不包含任何 iframe)时:

我看到了这个 :

>>$("iframe")

结果 :

[
<iframe name=​&quot;fb_xdm_frame_http" frameborder=​&quot;0" allowtransparency=​&quot;true" scrolling=​&quot;no" id=​&quot;fb_xdm_frame_http" aria-hidden=​&quot;true" title=​&quot;Facebook Cross Domain Communication Frame" tab-index=​&quot;-1" src=​&quot;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=​&quot;border:​ none;​&quot;>​…​&lt;/iframe>​
, 
<iframe name=​&quot;fb_xdm_frame_https" frameborder=​&quot;0" allowtransparency=​&quot;true" scrolling=​&quot;no" id=​&quot;fb_xdm_frame_https" aria-hidden=​&quot;true" title=​&quot;Facebook Cross Domain Communication Frame" tab-index=​&quot;-1" src=​&quot;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=​&quot;border:​ none;​&quot;>​…​&lt;/iframe>​
]

我读到它们用于跨域。

但问题是为什么他们在我的页面上

它们应该在 facebook 内部页面的某个地方!

我这么说是因为我知道Iframe 技术是这样工作的:

在此处输入图像描述

如您所见 - 内部 iframe 使用来自查询字符串的值创建另一个iframe SRC(该值实际上是首页 url),然后,在两个页面上使用 JS + URL => JS 触发函数,我们可以这样做:

top.sendData({...})

我错过了什么?

  • 数据如何从 FB 登录传递到我的页面?
4

2 回答 2

37

我是在 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 及其资源是隔离的——我们在此之上构建的任何服务都可以依赖于一个非常简单的 api,send_this_message(message, origin)并且它会“神奇地”结束另一方面,如果我们的原产地检查允许的话。

我希望这回答了你的问题!


(xd_arbiter.php 也可以用作重定向目标,它将使用它的兄弟代理来中继消息)。

于 2013-05-31T20:40:29.740 回答
0

我认为这个概念可以很简单,具体取决于您的代码中是否为 ie8+。

CORS 可用于跨域通信。确保在您的主机上设置了正确的标题并且您很好。

或者,创建一个 iframe,将其 src 设置为将信息传递给动态脚本的东西。处理信息。将 JS 代码返回到使用 postMessage 与外部窗口通信的 iframe。

于 2013-08-13T22:11:38.230 回答