Allowing a child Iframe to call a function on its parent window from a different domain

I have made a page which gets loaded in an IFrame and it needs to call a function on the parent page after it finishes loading.

It works locally in development (on the same domain) but in the Real World it is hosted on a completely different domain, so obviously I am running into Cross domain problems, ie:

Unsafe JavaScript attempt to access frame with URL http://[...]site1.com from frame with URL http://[...]site2.com/iframe. Domains, protocols and ports must match.

I control both the servers, so is it possible for me to put something on one or both of the servers that says they're allowed to talk to each other?

I have looked at setting "document.domain" in both the Iframe page and the parent page.

I have experimented with setting the Access Control Header:

header('Access-Control-Allow-Origin: *');

But neither of those work.

Is there any way of allowing an Iframe calling a function in the Parent window on a completely different domain when I control both servers?

Answers:

Answer

You can communicate between frames via the message posting API.

For example, in your child frame you might call:

parent.postMessage("child frame", "*");

And in the parent frame, register a message handler:

window.addEventListener("message", function(event) {
    console.log("Hello from " + event.data);
});
Answer

This problem can be easily solved by using an .htaccess rewrite.

Demo:

A. Create a directory named "iframeContent/" on SERVER 1.

B. Place in that directory a file named index.php containing:

<html> 
<head></head> 
<body>

<script type="text/javascript">

    parent.check();

</script>

</body> 
</html>

This is the content of the iFrame. It will call a function in a parent.

C. Create a directory named "iframeTesting_without-htaccess/" on SERVER 2.

D. Place in that directory a file named index.php containing:

<html> 
<head></head> 
<body>

<script type="text/javascript">

    function check() { 

       alert("hello");

    }

</script>

<iframe id="sidebnrId" name="sidebnr"
src="PATH-ON-SERVER-1/iframeContent/" frameborder="0"
height="500px" width="600px" scrolling="no"></iframe>

</script>

</body> 
</html>

This is simply the content of the parent windows. Just note that the iFrame content is located on another server (because on SERVER 1).

E. Access "PATH-ON-SERVER-2/iframeTesting_without-htaccess/" with a web-browser -> nothing happens: the iframe does not have access to the function of its parent.

HERE IS HOW YOU CAN SOLVE THE PROBLEM

F. Create another directory named "iframeTesting_with-htaccess/" on SERVER 2.

G. Place in that directory a file named index.php containing:

<html> 
<head></head> 
<body>

<script type="text/javascript">

    function check() { 

       alert("hello");

    }

</script>

<iframe id="sidebnrId" name="sidebnr"
src="content-iframe/" frameborder="0"
height="500px" width="600px" scrolling="no"></iframe>

</script>

</body> 
</html>

This time the iFrame does not point anymore directly to the content on SERVER 1 but to an intermediate fictive directory "content-iframe/" located on the same server (SERVER 2).

H. Place in that directory a .htaccess file containing:

Options +FollowSymLinks
RewriteEngine On

RewriteBase /

RewriteRule ^content-iframe/$ PATH-ON-SERVER-1/iframeContent/ [R,NC,P]

The role of that file is to redirect any access to the fictive directory to the content on the SERVER 1.

I. Try again, access "PATH-ON-SERVER-2/iframeTesting_with-htaccess/" with a web-browser. This time it will work. I hope it helped :-)

Answer

In modern browsers, you can use window.postMessage() to communicate between cooperating frames on different domains. You can't call a function directly, but you can pass data or messages between the two. See the description on MDN.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.