Julian Jelfs’ Blog

Cross-domain automatic iframe resizing

Posted in Uncategorized by julianjelfs on December 3, 2009

As we all know there are security restrictions when script from domain A tries manipulate content from domain B. This causes a lot of inconvenience. One example is automatic iframe resizing. It sounds simple on the face of it. When your iframe content loads you just need to tell the parent window what the content size is and then it can resize the iframe for you. The problem is that if the iframe content does not come from the same domain as the main page, you cannot do this. At least you cannot do this in the way you expect to.

This is a fairly well documented problem and the most common solution is to use the url fragment identifier hack. Basically this hack exploits the fact that any window or frame can set the location of any other window or frame (although perhaps counter intuitively it cannot read the location of a window from a different domain).

This trick can be used to accomplish cross-domain iframe resizing. Having googled this subject I found a good post on how to do this here. While the code in that post works well, I think it is quite verbose and in the end I reduced it to the following:

For each frame on the page, set the hash fragment of the frame’s src attribute to be the frame’s id:

<iframe id="myFrame"
    scrolling="no"
    frameborder="0"
    width="100%"
    src="whatever.aspx?name=val#myFrame">
</iframe>

In the main page add the following script to execute when the page starts up (I’m using jQuery here but you don’t have to):

window.setInterval(function(){
    var hash = window.location.hash.replace("#","");
    if(hash.length == 0)
        return;

    var pair = hash.split("=");
    $("#"+pair[0]).animate({height:pair[1]});
    window.location.hash = "";
}, 100);
and in each content page being loaded add the follow script to execute when the page starts up:
window.setInterval(function(){
    if(top == self)
        return;

    var bh = $("body").height();
    var wh = $(window).height();

    if  (Math.abs(bh - wh) > 10){
        var hash = self.location.hash.replace("#","");
        if(hash.length == 0)
            return;
        top.location.hash = hash + "=" + (bh + 10);
    }
}, 100);

What’s happening? Each content window is running a loop which detects if its window is either too big or too small and if it is, it writes a name value pair containing the id of the frame and the required height e.g. frameId=500 to the hash fragment of the main window’s url. It gets the frameId from its own hash fragment. This is allowed because we are simply writing to the hash, not trying to read. It will not cause a reload because we are only updating the hash fragment.

Meanwhile the main page is running a loop to monitor its own hash fragment looking for modifications made by the frames. When it finds a name value pair in its hash fragment it simply finds the corresponding frame and sets its height (animation an optional extra).

Obviously you can set the interval on the loops to whatever is appropriate.

Advertisements

6 Responses

Subscribe to comments with RSS.

  1. Yuko Stpierrie said, on March 3, 2010 at 7:29 am

    Fantastic post, I bookmarked your blog post so I can visit again in the near future, Cheers, Yuko Stpierrie

  2. evan said, on July 15, 2010 at 12:31 pm

    this only works in FireFox.

    This doesn’t work in IE, Safari or Chrome browsers.

    • julianjelfs said, on July 15, 2010 at 12:44 pm

      I’m sure you can fix it! The concept works though there are some quirks. I would double check but I moved on from this approach to something a bit more transparent. Basically I wrote a jquery plugin based on Julien Lecomte’s yui crossframe approach (http://www.julienlecomte.net/blog/2007/11/31/). I would really recommend checking out that blog post for a better solution.

      • Cinnak said, on August 21, 2010 at 9:26 pm

        Could you please share that script? I’ve been looking for a more solid solution for this for a long time.
        Thanks!

  3. dota2hack.org said, on November 14, 2014 at 10:10 am

    Wow I’m not sure if it is me or even your website but it’s launching incredibly slowly , I
    had to spend just like a few moments to load
    up however , gmail does work fine . Well, Thanks for placing such a fantastic blog post.
    I’m sure it has already been totally useful to individual who visit here.
    I ought to mention that you really have done brilliant job with this plus
    wish to find further awesome content through you. After
    checking out the blog post, I’ve book marked your site.

  4. Dakota said, on July 21, 2015 at 9:48 am

    Heya I am not sure if it’s me or even your internet
    site but it’s launching slow to me, I had to spend for a few minutes
    to finally load still , facebook operates totally .
    Nevertheless, Thanks for posting an extraordinarily
    awesome blog post. I think it has been literally
    helpful individual who seem to click here. I must tell you that you actually have done fantastic work with
    this and also wish to see more amazing stuff from you.
    Soon after checking out the post, I have book-marked your webblog.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: