Javascript 从 iframe 调用父窗口函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2161388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling a parent window function from an iframe
提问by Arjun Singh
I want to call a parent window JavaScript function from an iframe.
我想从 iframe 调用父窗口 JavaScript 函数。
<script>
function abc()
{
alert("sss");
}
</script>
<iframe id="myFrame">
<a onclick="abc();" href="#">Call Me</a>
</iframe>
回答by rahul
<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.
当窗口在、 或 中加载时<iframe>,其父窗口是元素嵌入窗口的窗口。<object><frame>
回答by Ash Clarke
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.
您要从子 iframe 调用的 javascript 需要位于父 iframe 的头部。如果在正文中,则该脚本在全局范围内不可用。
<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.
希望这可以帮助任何再次偶然发现此问题的人。
回答by Andrii Verbytskyi
Window.postMessage()
Window.postMessage()
This method safely enables cross-origincommunication.
这种方法可以安全地启用cross-origin通信。
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:
如果您有权访问父页面代码,则可以调用任何父方法以及可以直接从Iframe. 这是一个小例子:
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).
*如果您知道其他窗口的文档应该位于何处,请始终提供特定的 targetOrigin,NOT 。未能提供特定目标会泄露您发送到任何感兴趣的恶意站点的数据(来自ZalemCitizen 的评论)。
References:
参考:
回答by Ash Clarke
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.
这个问题最近再次出现,因为从引用子域的 iframe 访问父级,并且现有的修复程序不起作用。
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 checksinto thinking they co-exist on exactly the same domain (subdomains are considered a different host and fail the same origin policy check).
这次的答案是修改父页面的document.domain和iframe的相同。这会使同源策略检查误认为它们在完全相同的域中共存(子域被认为是不同的主机并且未通过同源策略检查)。
Insert the following to the <head>of the page in the iframe to match the parent domain (adjust for your doctype).
将以下内容插入<head>iframe 中的页面以匹配父域(根据您的文档类型进行调整)。
<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:
请注意,这会在 localhost 开发中引发错误,因此请使用如下检查来避免该错误:
if (!window.location.href.match(/localhost/gi)) {
document.domain = "mydomain.com";
}
回答by Vinothkumar Arputharaj
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>
回答by Devon
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.
为需要它的人提供的另一个补充。如果他们使用不同的协议,Ash Clarke 的解决方案将不起作用,因此请确保如果您使用 SSL,您的 iframe 也使用 SSL,否则会破坏功能。不过,他的解决方案确实适用于域本身,因此感谢您。
回答by Seph Remotigue
parent.abc()will only work on same domain due to security purposes. i tried this workaround and mine worked perfectly.
出于安全目的,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>
Hope this helps. :)
希望这可以帮助。:)
回答by Frato
The solution given by Ash Clarke for subdomains works great, but please note that you need to include the document.domain = "mydomain.com"; in both the head of the iframe page and the head of the parent page, as stated in the link same origin policy checks
Ash Clarke 为子域提供的解决方案效果很好,但请注意,您需要包含 document.domain = "mydomain.com"; 在 iframe 页面的头部和父页面的头部,如链接同源策略检查中所述
An important extension to the same origin policy implemented for JavaScript DOM access (but not for most of the other flavors of same-origin checks) is that two sites sharing a common top-level domain may opt to communicate despite failing the "same host" check by mutually setting their respective document.domain DOM property to the same qualified, right-hand fragment of their current host name. For example, if http://en.example.com/and http://fr.example.com/both set document.domain to "example.com", they would be from that point on considered same-origin for the purpose of DOM manipulation.
为 JavaScript DOM 访问实现的同源策略的一个重要扩展(但不适用于大多数其他类型的同源检查)是,尽管“同一主机”失败,共享公共顶级域的两个站点可能会选择通信通过将它们各自的 document.domain DOM 属性相互设置为它们当前主机名的相同限定右侧片段来进行检查。例如,如果http://en.example.com/和http://fr.example.com/都将 document.domain 设置为“example.com”,则从那时起,它们将被视为同源DOM 操作的目的。
回答by snowflake
With Firefox and Chrome you can use :
使用 Firefox 和 Chrome,您可以使用:
<a href="whatever" target="_parent" onclick="myfunction()">
If myfunction is present both in iframe and in parent, the parent one will be called.
如果 iframe 和父级中都存在 myfunction,则将调用父级。
回答by William J. Littlefield
While some of these solutions may work, none of them follow best practices. Many assign global variables and you may find yourself making calls to multiple parent variables or functions, leading to a cluttered, vulnerable namespace.
虽然其中一些解决方案可能有效,但它们都没有遵循最佳实践。许多分配全局变量,您可能会发现自己调用了多个父变量或函数,导致命名空间混乱、易受攻击。
To avoid this, use a module pattern. In the parent window:
为避免这种情况,请使用模块模式。在父窗口中:
var myThing = {
var i = 0;
myFunction : function () {
// do something
}
};
var newThing = Object.create(myThing);
Then, in the iframe:
然后,在 iframe 中:
function myIframeFunction () {
parent.myThing.myFunction();
alert(parent.myThing.i);
};
This is similar to patterns described in the Inheritance chapter of Crockford's seminal text, "Javascript: The Good Parts." You can also learn more at w3's page for Javascript's best practices. https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals
这类似于 Crockford 开创性文本“Javascript: The Good Parts”的继承章节中描述的模式。您还可以在 w3 的页面上了解有关 Javascript 最佳实践的更多信息。https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals

