Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a parent window function from an iframe

People also ask

Can iframe call function in parent?

You can call code of the parent window form child window. f you open window by using iframe, you can communicate from child window with the parent. <button onclick="onClick();">Call Parent Window Function</button>When you open Page1.

How do you call a parent page of an iframe function?

To call a parent window function, use “window. top”.

Can iframe access parents?

When a page is running inside of an iframe, the parent object is different than the window object. You can still access parent from within an iframe even though you can't access anything useful on it. This code will never cause an error even when crossing origins.


<a onclick="parent.abc();" href="#" >Call Me </a>

See window.parent

Returns a reference to the parent of the current window or subframe.

If a window does not have a parent, its parent property is a reference to itself.

When a window is loaded in an <iframe>, <object>, or <frame>, its parent is the window with the element embedding the window.


Window.postMessage()

This method safely enables cross-origin communication.

And if you have access to parent page code then any parent method can be called as well as any data can be passed directly from Iframe. Here is a small example:

Parent page:

if (window.addEventListener) {
    window.addEventListener("message", onMessage, false);        
} 
else if (window.attachEvent) {
    window.attachEvent("onmessage", onMessage, false);
}

function onMessage(event) {
    // Check sender origin to be trusted
    if (event.origin !== "http://example.com") return;

    var data = event.data;

    if (typeof(window[data.func]) == "function") {
        window[data.func].call(null, data.message);
    }
}

// Function to be called from iframe
function parentFunc(message) {
    alert(message);
}

Iframe code:

window.parent.postMessage({
    'func': 'parentFunc',
    'message': 'Message text from iframe.'
}, "*");
// Use target origin instead of *

UPDATES:

Security note:

Always provide a specific targetOrigin, NOT *, if you know where the other window's document should be located. Failing to provide a specific target discloses the data you send to any interested malicious site (comment by ZalemCitizen).

References:

  • Cross-document messaging
  • Window.postMessage()
  • Can I Use

I recently had to find out why this didn't work too.

The javascript you want to call from the child iframe needs to be in the head of the parent. If it is in the body, the script is not available in the global scope.

<head>
    <script>
    function abc() {
        alert("sss");
    }
    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="parent.abc();" href="#">Click Me</a>
    </iframe>
</body>

Hope this helps anyone that stumbles upon this issue again.


I have posted this as a separate answer as it is unrelated to my existing answer.

This issue recently cropped up again for accessing a parent from an iframe referencing a subdomain and the existing fixes did not work.

This time the answer was to modify the document.domain of the parent page and the iframe to be the same. This will fool the same origin policy checks into thinking they co-exist on exactly the same domain (subdomains are considered a different host and fail the same origin policy check).

Insert the following to the <head> of the page in the iframe to match the parent domain (adjust for your doctype).

<script>
    document.domain = "mydomain.com";
</script>

Please note that this will throw an error on localhost development, so use a check like the following to avoid the error:

if (!window.location.href.match(/localhost/gi)) {
    document.domain = "mydomain.com";
} 

You can use

window.top

see the following.

<head>
    <script>
    function abc() {
        alert("sss");
    }
    </script>
</head>
<body>
    <iframe id="myFrame">
        <a onclick="window.top.abc();" href="#">Click Me</a>
    </iframe>
</body>

Another addition for those who need it. Ash Clarke's solution does not work if they are using different protocols so be sure that if you are using SSL, your iframe is using SSL as well or it will break the function. His solution did work for the domains itself though, so thanks for that.