从iframe调用父窗口函数

Arj*_*ngh 270 javascript iframe onclick

我想从iframe调用父窗口JavaScript函数.

<script>
    function abc()
    {
        alert("sss");
    }
</script>

<iframe id="myFrame">
    <a onclick="abc();" href="#">Call Me</a>
</iframe>
Run Code Online (Sandbox Code Playgroud)

rah*_*hul 425

<a onclick="parent.abc();" href="#" >Call Me </a>
Run Code Online (Sandbox Code Playgroud)

请参见window.parent

返回对当前窗口或子帧的父级的引用.

如果窗口没有父窗口,则其父属性是对自身的引用.

当在一个被加载的窗口<iframe>,<object>或者<frame>,它的父是与元件嵌入窗口的窗口.

  • 始终考虑到父文档和iframe文档必须按协议和域名匹配.如果没有发生,那么您将收到安全错误,因为它不允许具有跨域脚本. (14认同)
  • @ a4bike对于这种情况,`window.postMessage()`(或`window.parent.postMessage()`)存在.检查[@Andrii答案](http://stackoverflow.com/a/41566923/1369473) (3认同)

Ash*_*rke 78

我最近不得不找出为什么这也不起作用.

您要从子iframe调用的javascript需要位于父级的头部.如果它在正文中,则脚本在全局范围内不可用.

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

希望这可以帮助任何再次遇到这个问题的人.

  • 如果我没记错的话,如果iframe与父母的域名不同,我就无法按预期工作.对不起,这不是一个解决方案,但它可以解释为什么它不起作用. (3认同)
  • 本文中提到的技术均不适用于 Chrome。有什么解决办法吗? (2认同)

And*_*kyi 60

Window.postMessage()

此方法可安全地进行cross-origin通信.

如果您可以访问父页面代码,则可以调用任何父方法,也可以直接从中传递任何数据Iframe.这是一个小例子:

父页面:

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);
}
Run Code Online (Sandbox Code Playgroud)

iframe代码:

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

参考文献:

  • 与其他人相比,我更喜欢使用这个。特别是因为在跨源文档上使用 iframe 更有意义(尽管程序员确实经常利用 iframe),并且考虑到浏览器对此功能的广泛支持。 (2认同)
  • 谢谢!我总是需要花一个小时或更长时间回去研究如何用过于复杂、冗长的例子来传递信息。这在 60 秒内起作用。感谢您提供一个简洁明了的例子。 (2认同)
  • 值得提出来(从[MDN Web文档](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)):如果您知道,请始终提供特定的targetOrigin,而不是*另一个窗口的文档应位于的位置。未能提供特定的目标会泄露您发送到任何感兴趣的恶意站点的数据 (2认同)

Ash*_*rke 19

我将此作为单独的答案发布,因为它与我现有的答案无关.

此问题最近再次出现,用于从引用子域的iframe访问父级,并且现有修补程序不起作用.

这次的答案是修改父页面的document.domain和iframe是相同的.这将欺骗相同的原始策略检查,认为它们共存于完全相同的域(子域被视为不同的主机并且未通过相同的原始策略检查).

将以下内容插入<head>iframe中的页面以匹配父域(根据您的doctype进行调整).

<script>
    document.domain = "mydomain.com";
</script>
Run Code Online (Sandbox Code Playgroud)

请注意,这将在localhost开发中引发错误,因此请使用如下所示的检查来避免错误:

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

  • 值得注意的是(至少在Google Chrome中)父母和孩子都必须设置document.domain,即使其中一个已经"正确"了!示例:Parent是`example.com` iframe是`abc.example.com`,然后parent和iframe都必须调用`document.domain ="example.com"` (2认同)

Vin*_*raj 16

您可以使用

window.top
Run Code Online (Sandbox Code Playgroud)

请参阅以下内容.

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

  • 当尝试调用parent.custom_function();时 从 iframe 不起作用,您可能会发现 window.top.custom_function(); 将工作。由于某些奇怪的原因对我有用。我在父窗口上的 javascript 都嵌入在页脚中,我在某处读到,在页脚中包含 javascript 文件会导致问题parent.custom_function() 不起作用。 (2认同)