Finally found how FB do it :)
- page_proxy.php#frameName - loads a form which then loads our iframe with signed request using POST method.
Why there is no direct call to load iframe with app? To prevent 3rd party scripts to get signed request (which contains all user info).
How fb do it (adopted code by me):
<form method="post" id="proxy_form"><input type="hidden" autocomplete="off" id="signed_request" name="signed_request" /></form>
<script>
var frameName = window.location.href.split('#')[1];
function submitForm(appTabUrl, signedRequest) {
var proxyForm = document.getElementById("proxy_form");
proxyForm.setAttribute("action", appTabUrl);
proxyForm.setAttribute("target", frameName);
var input = document.getElementById("signed_request");
input.setAttribute("value", signedRequest);
proxyForm.submit();
}
function waitForParams() {
submitForm('$url_with_app', 'signed_request_goes_here');
}
waitForParams();</script>
App in iFrame loads normally but we dont see iframe with our app in the DOM Browser because its loaded using POST request.
We initialize facebook in our app and tell to Autogrow our app.
Facebook completes initialization, wait till DOM will be ready and calculate height of the app.
Now is time to grow our iframe. And here is the trick they do:
_sendMessageToFacebook: function(message) {
var url = FB._domain.staticfb + 'connect/canvas_proxy.php#' +
FB.QS.encode({method: message.method,
params: FB.JSON.stringify(message.params)});
var root = FB.Content.appendHidden('');
FB.Content.insertIframe({
url: url,
root: root,
width: 1,
height: 1,
onload: function() {
setTimeout(function() {
root.parentNode.removeChild(root);
}, 10);
}
});
}
They load another iframe inside our application but that iframe already belongs to facebook and can interact with the FB parent (top window) and send to parent all required information!