Question

We're implementing an OAuth API for our service and will be supporting applications too.

First thing which I wanted to do - allow autoresizing for app iframe.

Stuck.

  • In parent document I can't get size of an iframe content if iframe is on other domain.
  • I can't interact with parent document/scripts from my iframe because the iframe is on other domain.

But Facebook does it somehow??

I tried to hack their app loading flow but without any success.

They load page_proxy.php in an iframe then somehow code from application gets inside that iframe.

Of course it can be that they simply get html contents from an app and then translate all url paths to absolute.. but. Then HOW Ajax calls work (if they are simply loading our html contents - then any ajax call is becoming a crossdomain call)? But it all does work on FB as if my app was loaded as a real iframe and there are no any crossdomain calls..! But then again.. how resizing works and why I dont see my iframe on facebook and see only pageproxy??

Really need some light here.

Thanks.

Was it helpful?

Solution

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:

Source from FB

_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!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top