15

I have an iframe being created on a page, and the page's domain is being explicitly set to 'xyz.com' but the iframe's domain is defaulting to 'dev.xyz.com', which is the actual domain i'm developing for.

The problem is, when I try to access that iframe via iframe.contentWindow.document, it fails due to the difference in domain.

I've tried setting the iframe's src to a file with document.domain = 'xyz.com' but that doesn't seem to be doing the trick...

Any ideas?

Matt Cain
  • 5,638
  • 3
  • 36
  • 45
Chris
  • 151
  • 1
  • 1
  • 3
  • As a follow up, here is the code that is creating the iframe, and attempting to access it: jQuery("body").prepend(''); var ihistory = jQuery("#jQuery_history")[0]; var iframe = ihistory.contentWindow.document; – Chris Dec 23 '09 at 00:07
  • 1
    This library supports HTML5 postMessage and legacy browsers with resize+hash https://github.com/ternarylabs/porthole (Ben Alman's jQuery Plugin hasn't been touched in 3 years) – jpillora Feb 27 '13 at 14:43
  • Ben Alman has an awesome jquery plug-in that can be used to solve this problem. http://benalman.com/projects/jquery-postmessage-plugin/ – Justin Apr 06 '11 at 13:46
  • I believe you need to set both the iframe's document.domain and the main page's document.domain to the same thing. ([more info here](http://jszen.blogspot.com/2005/03/cross-domain-security-woes.html)) – Alconja Dec 22 '09 at 23:25
  • Since you have access to both parent and iframe, I'd recommend the following read: http://www.onlineaspect.com/2010/01/15/backwards-compatible-postmessage/ – Kyle Cureau Nov 23 '10 at 00:32
  • you can also use some handshaking using this library https://github.com/mdx-dev/inception – Rulian Dec 26 '13 at 13:53

3 Answers3

12

Page inside iframe:

<script>
document.domain = document.domain;
</script>

It looks silly, but it works. See "What does document.domain = document.domain do?".

Community
  • 1
  • 1
NVI
  • 14,907
  • 16
  • 65
  • 104
  • 1
    This dirty hack will interfere, when you'll be having **Access-Control-Allow-Origin** requests, alike CDNs in AJAX loads from JS. Be careful in using it. – Farside Mar 21 '16 at 18:45
8

After some research, I found this jQuery plugin that makes postMessage backwards-compatible with older browsers using various tricks.

Here is a quick example showing how to send the height of the iframe's body to the parent window:

On the host (parent) page:

    // executes when a message is received from the iframe, to adjust 
    // the iframe's height
    $.receiveMessage(
        function( event ){
            $( 'my_iframe' ).css({
                height: event.data
            });
    });
   // Please note this function could also verify event.origin and other security-related checks.

On the iframe page:

$(function(){

    // Sends a message to the parent window to tell it the height of the 
    // iframe's body        
    var target = parent.postMessage ? parent : (parent.document.postMessage ? parent.document : undefined);

    $.postMessage(
        $('body').outerHeight( true ) + 'px',
        '*',
        target
    );

});

I've tested this on Chrome 13+, Firefox 3.6+, IE7, 8 and 9 on XP and W7, safari on OSX and W7. ;)

Jujhar Singh
  • 3,641
  • 5
  • 29
  • 38
0x6A75616E
  • 4,696
  • 2
  • 33
  • 57
0

As a addition to the reference to the Ben Alman plug in I thought I would post this working example. It ]rRelies on an iframe which has a source page containing jquery authentication & data query script which then passes the result to {other domain} parent window using the message plugin.

NB message plugin will break if using JQ v9 as JQV9 does not use "browser" referenced in the plugin

1st step: Add the plugin code to both sending and receiving docs:

http://benalman.com/projects/jquery-postmessage-plugin/

2nd step: Add this to sending doc:

   $.postMessage(
$(X).html(),    
'http://DOMAIN [PORT]/FOLDER/SUBFOLDER/RECIEVINGDOCNAME.XXX'   
 )  ;      

Where X can be a local var containing preformatted json array or other stuff, and the http url here is the address of the receiving document.

3rd step: Add this to receiving doc:

    $.receiveMessage(
    function(event){
        alert("event.data: "+event.data);
                $("#testresults").append('<h1>'+event.data+'<h1>');

    },          
    'http://DOMAIN.COM OR SOMETHING'

);

Where the http url is the DOMAIN of the sending document. Good in IE 8, 9, FF16, safari Windows (windows wait x V9 not tested yet), safari x mac thing.

The result is any item you want out of another domain page (that you have access to..).

Richard
  • 224
  • 1
  • 7
  • 18