Facebook and Cross domain messaging clarification?

Royi Namir picture Royi Namir · May 31, 2013 · Viewed 17.5k times · Source

I wanted to investigate how the facebook login transfer data to the main page ( mypage) - despite the cross domain boundary limitation.

And so I created a new page with the FB js sdk code :

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

It does open the popup :

enter image description here

But when I investigated to see if I have any Iframes on my page ( My code doesn't contain any iframes) :

I saw this :

>>$("iframe")

result :

[
<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>​
]

I read that they are used for the cross domain.

But the question is why are they on MY PAGE ?

They should be somewhere on facebook internal pages!

I'm saying it because I know that the Iframe technique works like this :

enter image description here

As you can see - the internal Iframe creates another iframe with the SRC value from query string (the value is the top page url actually) , and then , with JS on both pages + URL => JS trigger functions , we can do :

top.sendData({...})

What am I missing ?

  • How does the data is being passed from the FB login to my page ?

Answer

Sean Kinsey picture Sean Kinsey · May 31, 2013

I'm the engineer who designed the current infrastructure for Cross-Domain Messaging in the Facebook JS SDK, so maybe I can shed some light on things here.

This setup might seem a bit unorthodox and confusing to some, but it's really quite elegant, if I might say so myself :)


Depending on whether the page is HTTP or HTTPS, the JS SDK will create two iframes, pointing to the xd_arbiter.php resource, which is served from a *.facebook.com domain. Since it sets document.domain = 'facebook.com', these can communicate with other resources on facebook.com that does the same.

These resources, the proxies, gets passes some information through the fragment, to give them dynamic capabilities, but are otherwise 100% static and cached by your browser - so these are really fast to load.

What happens next is that a Cross-Domain Messaging link is established between the host page, and each of the iframes (the proxies). This means that from now on, the host page can communicate to a HTTPS page on facebook.com, and if the host page is HTTP, it can also communicate with a HTTP page on facebook.com.

How this link works across browsers is a more complex matter, but it's all abstracted into a channel, much like you can see with easyXDM.


Now, whenever the JS SDK creates a new window on facebook.com, either as a popup, or as an iframe, instead of having to set up a fresh communication channel between the host page and each window, the new windows can utilize the existing proxy, paying no cost in setup.

When needing to send messages to the host page, these will use (window.opener || window.parent).frames['fb_xdm_frame_' + location.protocol.replace(':', '') to get a handle to the proxy, and similarly, the proxy can use parent.frames[some_name] to get a handle to any sibling iframes on the page, as long as the right proxy (HTTP or HTTPS) was used.

For us, this basically means that the concern about how to communicate cross-domain is isolated to the JS SDK and its resources - any services we build on top of this can rely on a very simple api of send_this_message(message, origin) and it will 'magically' end up on the other end, if allowed by the origin checks we have in place.

I hope this answers your question!


(xd_arbiter.php can also serve as a redirect target, where it will use it's sibling proxies to relay the message).