Facebook和跨域消息传递澄清?

时间:2013-05-31 16:52:49

标签: javascript facebook cross-domain facebook-javascript-sdk

我想调查facebook登录如何将数据传输到主页面(mypage) - 尽管存在跨域限制。

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

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

它会打开弹出窗口:

enter image description here

但是当我调查我的网页上是否有任何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技术的工作原理如下:

enter image description here

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

top.sendData({...})

我错过了什么?

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

2 个答案:

答案 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。