DCSIMG
Cross IFrame communication solution - Pini Dayan

Pini Dayan

The best thing about a boolean is even if you are wrong, you are only off by a bit.

Cross IFrame communication solution

When we have a Web page hosting some other page with an IFrame in it we usually have no problems. But what happens if we try to host a page that is not our domain. This will work fine as long is there is no interaction between the hosting page and the IFrame source. As it turns out in the newer versions of IE there is a security issue when trying to access the DOM between the 2 Pages. (Or in other words when the 2 pages trying to "talk" to each other.

Lets se an example to this problem:

Lets say I have an ASPX file called p1.aspx which is the hosting page of some IFrame:

<form id="form1" runat="server">
    <div>
    This is the main page, with an iframe<br /><br />    
       <iframe src="p2.aspx" width="300px" width="100px"
            scrolling=yes name="MyIFrame"
            id="MyIFrame" frameborder=1>
            
    To view this content upgrade your browser.        
    </iframe>    
    <br />    
 </form>

And Lets say I have a p2.aspx file that is the src of the IFrame in p1.aspx. I now want these 2 pages to somehow interact, so here is what I do:

  • I am adding a button to p1.aspx to call some JavaScript method. These button will be used to change the src property of the IFrame to another page that is not in my domain.
  • <asp:Button runat=server Text="Change iframe to google"
          OnClientClick="ChangeIFrame();return false;" /><br />
  • I am adding another button that will call another JavaScript function that will change the innerHTML of the Iframe:
<asp:Button ID="Button1" runat=server 
      Text="Update Content of the IFRAME"
      OnClientClick="ChangeIFrameContent();return false;" /><br />  
  • Here is the code for the 2 JavaScript functions:
<script>           
   function ChangeIFrame()
   {    
       document.getElementById("MyIFrame").src =
                               "http://www.google.com"
   } 
   function ChangeIFrameContent()
   {  
        document.getElementById("MyIFrame").contentWindow.
                                  document.body.innerHTML = "222";
   }     
</script>
Now lets see what happens if I am trying to first change the IFrame src to www.google.com and then changing the content using the second button:
image 

So what do we do to solve it and when you try to look for a good solution you will see several.  I even worked once in a company that saved what ever she wanted in a DB and then every second checked if the DB with the given row was changes, took the values she needed and then apply them to the IFrame.(They had the 2 pages in a different domain but they had access to both of them).

So here is a good solution for this problem: (And this time with a different example).

Let's say I want my inner IFrame to change it's size if someone clicks some button inside it. I can't do it on his own since the page is hosted as an IFrame in a different page. Here comes the solution: In order to "talk" between the 2 pages the inner page will change it's own src and add a fragment identifier to the URL. When changing the URL by only adding it a fragment identifier the page will now reload.

The hosting page only have to check at each interval that the src of it's IFrame has changes and if so - do something. (Without busy waiting of course)

So here is the complete code for the first page:

This is the main page, with an iframe<br /><br />       
       <
iframe src=p4.aspx width="300px" width="100px" scrolling=yes
           
name="MyIFrame" id="MyIFrame" frameborder=1>111</iframe

1. The script for checking if the IFrame src has changed:
<script>  
    //Set a timer
    function CheckWidthOfIFrame()
    {              
        if(window.frames[0].location.href.indexOf("width") != -1)
        {
            var widthFragment = 
              window.frames[0].location.href.split("#")[1];
            var width = widthFragment.split("=")[1];   
            document.getElementById("MyIFrame").style.width = width;       
        }
        window.setTimeout("CheckWidthOfIFrame()",1000);
    }               
    </script>
Notice that I am using a window.setTimeout to avoid busy waiting.
We have to start this function on the page load:
<body onload="CheckWidthOfIFrame();">
2. The hosted page source:
html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
    <script>    
    function SetURL()
    {    
         location.href = location.href + "#width=500";
    }
    </script>
</head>
<body style="background-color:yellow">
    <form id="form1" runat="server">
    <div>
    I am an Iframe    
    <input type=button value="Change your size to 500px"
             onclick="SetURL()" />
    </div>
    </form>
</body>
</html>
And that's it!
 

Comments

Topics about Microsoft » Cross IFrame communication solution said:

Pingback from  Topics about Microsoft  &raquo; Cross IFrame communication solution

# April 22, 2009 4:21 PM

shlomo said:

תתחדש על הלוק החדש

# April 23, 2009 11:18 AM

faxless cash advance said:

I found beta.blogs.microsoft.co.il very informative. The article is professionally written and I feel like the author knows the subject very well. beta.blogs.microsoft.co.il keep it that way.

# June 29, 2009 1:40 PM

Pini Dayan said:

Thank you very much for the compliment :-)

# June 30, 2009 8:34 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: