Demonstrating Cross-Domain Iframe-Parent Interaction

The example below demonstrates an iframe using postMessage to interact with its parent document when that document is on another domain. Even though the Same Origin Policy prevents direct access to the objects and properties in the document, postMessage can be used to ask the document on the other domain to perform the tasks and provide the needed information.

Click the buttons in the iframe below to interact with the containing document as described. The JavaScript for the example is displayed below the iframe.


This example demonstrates the iframed document initiating interaction with its parent. A related example shows the containing document initiating interaction with the iframed document: parent to iframe.

JavaScript for the Example

Although this example performs the same tasks as that for same-domain cross-document communication, the JavaScript is much different.

The iframed document includes the following JavaScript. First, onclick handler functions are assigned to the buttons onload. When a button is clicked its associated task is sent to the parent document via postMessage.

// check for browser support
if ( window.addEventListener ) {
    
    // onload
    window.addEventListener('load', function() {
        // get reference to form to attach button onclick handlers
        var form = document.getElementById('iframeDemoForm');
        // where to send messages with postMessage
        var target_origin = 'http://www.dyn-web.com';
        
        // button onclick handlers
        // display offsetHeight of iframe containing this document
        form.elements.button1.onclick = function() {
            parent.postMessage( {'task': 'height'}, target_origin );
        }
        
        // increment and display counter variable contained in parent document
        form.elements['button2'].onclick = function() {
            parent.postMessage( {'task': 'ctr'}, target_origin );
        }
        
        // get value of parent doc's text box
        form.elements.button3.onclick = function() {
            parent.postMessage( {'task': 'val'}, target_origin );
        }
        
        // empty parent doc's text box
        form.elements.button4.onclick = function() {
            parent.postMessage( {'task': 'clear'}, target_origin );
        }
        
    }, false);
    
    
    // message handler
    window.addEventListener('message', function(e) {
        // check message origin
        if ( e.origin === 'http://www.dyn-web.com' ) {
            
            var task = e.data['task']; // task received in postMessage
            // get reference to demo form
            var form = document.getElementById('iframeDemoForm');
            
            switch ( task ) { // postMessage tasks
                // display height received in postMessage
                case 'height' :
                    form.elements.display.value = 'OffsetHeight of the iframe is: ' + e.data['height'] + 'px';
                    break;
                
                // display counter received in postMessage
                case 'ctr' :
                    form.elements.display.value = 'counter in parent document is: ' + e.data['counter'];
                    break;
                
                // display text box value received in postMessage
                case 'val' :
                    form.elements.display.value = 'The greeting is: ' + e.data['val'];
                    break;
                
                case 'clear' :
                    // nothing to do for this one
                    break;
                
                //default:
                    
            }
            
        }
    }, false);
}

A message handler response to postMessage replies from the containing document. A switch case branches based on the type of task and handles the reply received.

JavaScript in Parent Document

The JavaScript displayed here is included in this document to perform the tasks demonstrated above. It mainly consists of a message handler to respond to postMessage events from the iframed document. The tasks are handled in a switch case construct, and the results of the task are sent back to the source using postMessage.

// example variable and function for cross-document demo
var counter = 0;

function clearGreeting() {
    document.forms['demoForm'].elements['greeting'].value = '';
}

// check for browser support
if ( window.addEventListener ) {
    
    // message handler
    window.addEventListener('message', function (e) {
        // check message origin
        if ( e.origin === 'http://www.example.com' ) {
            var task = e.data['task']; // task received in postMessage
            // get reference to iframe window
            var win = document.getElementById('ifrm').contentWindow;
            
            switch ( task ) { // postMessage tasks
                // obtain height of iframe and send in postMessage
                case 'height' :
                    var ht = document.getElementById('ifrm').offsetHeight;
                    win.postMessage( {'task': 'height', 'height': ht}, e.origin );
                    break;
                
                // increment counter variable and send
                case 'ctr' :
                    win.postMessage( {'task': 'ctr', 'counter': ++counter}, e.origin );
                    break;
                
                // send value of entry in text box (validate first)
                case 'val' :
                    var re = /[^-a-zA-Z!,'?\s]/g; // to filter out unwanted characters
                    // get reference to greeting text box
                    var fld = document.forms['demoForm'].elements['greeting'];
                    var val = fld.value.replace(re, '');
                    win.postMessage( {'task': 'val', 'val': val}, e.origin );
                    
                    break;
                
                // clear text box by calling function
                case 'clear' :
                    clearGreeting();
                    break;
                
                //default:
                    
            }
        
        }
        
    }, false);
}

See a related example that demonstrates a document interacting with an iframe on another domain to request information about its objects and properties.