从iframe调用父窗口函数

我想从一个iframe调用一个父窗口JavaScript函数。

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

见window.parent

返回对当前窗口或子帧的父项的引用。

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

当一个窗口被加载到一个<iframe><object>或者<frame> ,它的父窗口就是embedded窗口的窗口。

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

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

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

希望这可以帮助任何人再次绊倒这个问题。

我已经发布这个作为一个单独的答案,因为它是与我现有的答案无关。

这个问题最近再次出现,从一个引用一个子域的iframe中访问一个父母,现有的修复无法正常工作。

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

将以下内容插入iframe中页面的<head>以匹配父域(调整您的文档types)。

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

请注意,这将在localhost开发中引发错误,所以请使用类似以下的检查来避免错误:

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

您可以使用

 window.top 

请参阅以下内容。

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

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); } 

Iframe代码:

 window.parent.postMessage({ 'func': 'parentFunc', 'message': 'Message text from iframe.' }, "*"); 

参考文献:

  • 跨文档消息
  • Window.postMessage()
  • 我可以用吗

另一个需要它的人。 Ash Clarke的解决scheme如果使用不同的协议,则不起作用,因此如果您使用的是SSL,则iframe也会使用SSL,否则将会中断该function。 他的解决scheme确实为域名本身工作,所以非常感谢。

Ash Clarke给出的子域名解决scheme效果很好,但请注意,您需要包含document.domain =“mydomain.com”; 在iframe页面的头部和父页面的头部,如链接相同来源策略检查中所述

对于JavaScript DOM访问(但不适用于大多数其他风格的同源检查)实施的相同原始策略的重要扩展是共享公共顶级域的两个站点可能select通信,尽pipe“相同主机”通过相互设置它们各自的document.domain DOM属性来检查它们当前主机名的相同合格的右边片段。 例如,如果http://en.example.com/和http://fr.example.com/都将document.domain设置为“example.com”,那么他们将从这个angular度考虑同源DOM操作的目的。;

由于安全目的, parent.abc()只能在同一个域上工作。 我试过这个解决方法,我的工作完美。

 <head> <script> function abc() { alert("sss"); } // window of the iframe var innerWindow = document.getElementById('myFrame').contentWindow; innerWindow.abc= abc; </script> </head> <body> <iframe id="myFrame"> <a onclick="abc();" href="#">Click Me</a> </iframe> </body> 

希望这可以帮助。 🙂

使用Firefox和Chrome,您可以使用:

 <a href="whatever" target="_parent" onclick="myfunction()"> 

如果myfunction和iframe都存在,则会调用父函数。

虽然其中一些解决scheme可能有效,但是没有一个遵循最佳实践。 许多分配全局variables,你可能会发现调用多个父variables或函数,导致一个混乱,易受攻击的名称空间。

为了避免这种情况,请使用模块模式。 在父窗口中:

 var myThing = { var i = 0; myFunction : function () { // do something } }; var newThing = Object.create(myThing); 

然后,在iframe中:

 function myIframeFunction () { parent.myThing.myFunction(); alert(parent.myThing.i); }; 

这与Crockford的开创性文本“Javascript:The Good Parts”的inheritance一章中描述的模式类似。 您也可以在W3的页面了解更多有关Javascript最佳实践的信息。 https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals