Working around cross-origin issues with iFrames

While working on an internal system I was using an iFrame to load a web page from a different domain from the one the it was sat on (e.g. parent page: website-one.com, iFrame: website-two.co.uk) As development continued it became clear the parent page needed to interact with the iFrame page, and vice-versa.

After some testing and a bit of research it was clear that this wouldn’t easily work due to browser’s same-origin policies – an understandable security mechanism (see Mozilla’s page on it here)

There are a couple of ways around this, the I started with a proxy page through which all of the iFrame pages would be loaded through (based on Ben Alman’s simple PHP proxy) – this proved to be troublesome as we were loading resources from all over the place and of many different types so the idea was quickly scrapped.

After some more research I settled on the JavaScript ‘.postMessage()‘ model. Although it was essentially a basic client-server model it suited our needs and worked wonders. Here’s a quick run down:

First step is sending data from the parent (website-one.com) to the child (website-two.co.uk)

var iframe = document.getElementById('iframe-id').contentWindow;

iframe.postMessage({ data: 'data here' }, 'http://website-two.co.uk');

Next is listening for this message on the child page

function processMessage(message) {

    // Filter out messages from other origins
    if (message.origin !== 'website-one.com') {
        return;
    }

    console.log(message.data);
}

window.addEventListener('message', processMessage, false);

In this case the function will post a message to the console of ‘data here’ (as per our request). You can listen out for whatever message you want and process it as you like.

Sending data back to the parent is just as simple

parent.postMessage({ data: 'return data!'}, 'http://website-one.com');

Although the parent web page will also require a listener to receive the data.

It does require more work than just directly interacting with the iFrame from the parent page but I’ve found it to work a treat for our use case – particularly as there are so few alternatives!

Quick tip: when using jQuery you can access the iFrame as follows: $('#iframe-id')[0].contentWindow

Advertisements

Published by:

Skyrail

Production Facilitator at Audacious Church Previously Software Developer at UKFast Ltd. and Web Applications Developer at SenseLogix Ltd. Graduate of Renewable Energy BSc from the University of Exeter. Experience with PHP, MySQL, Javascript, CSS and HTML.

Categories Javascript, Web DevelopmentLeave a comment

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