从iframe中调用父窗口函数

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

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


<iframe id="myFrame">
<a onclick="abc();" href="#">Call Me</a>
</iframe>
489221 次浏览
<a onclick="parent.abc();" href="#" >Call Me </a>

看到window.parent

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

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

当一个窗口在<iframe><object><frame>中加载时,它的父元素就是嵌入该窗口的元素所在的窗口。

最近,我不得不找出为什么这种方法也不起作用。

你想从子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>

希望这能帮助到再次遇到这个问题的人。

你可以使用

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>

我把这个作为一个单独的答案,因为它与我现有的答案无关。

这个问题最近在从引用子域的iframe访问父节点时再次出现,现有的修复不起作用。

这一次的答案是修改文件。父页面的域和iframe必须相同。这将欺骗同源策略检查,使其认为它们共存于完全相同的域中(子域被认为是不同的主机,同源策略检查失败)。

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

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

请注意,这将在本地主机开发时抛出一个错误,所以使用如下检查来避免错误:

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

Ash Clarke为子域名提供的解决方案很好,但请注意,您需要包括文档。域名= "mydomain.com";在iframe页面的头部和父页面的头部,如链接同源策略检查中所述

为JavaScript DOM访问实现的同源策略的一个重要扩展(但并不适用于大多数其他类型的同源检查)是,共享一个公共顶级域的两个站点可以选择通信,尽管通过相互设置各自的文档未能通过“相同主机”检查。domain DOM属性设置为当前主机名的相同限定的右侧片段。 例如,如果http://en.example.com/http://fr.example.com/都设置文档。

. domain到"example.com",为了DOM操作的目的,它们将从那一点开始被认为是同源的

这是为有需要的人准备的。如果它们使用不同的协议,Ash Clarke的解决方案就不起作用,所以如果您使用SSL,请确保您的iframe也使用SSL,否则将破坏功能。他的解决方案确实适用于域名本身,所以谢谢你。

出于安全考虑,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和parent中,父函数将被调用。

虽然其中一些解决方案可能有效,但没有一个符合最佳实践。许多分配全局变量,您可能会发现自己调用多个父变量或函数,导致混乱、易受攻击的命名空间。

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

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”的继承章节中描述的模式。你也可以在w3的页面上了解更多Javascript的最佳实践。https://www.w3.org/wiki/JavaScript_best_practices#Avoid_globals

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.'
}, "*");
// Use target origin instead of *

更新:

安全注意事项:

如果你知道另一个窗口的文档应该位于哪里,总是提供一个特定的targetOrigin,而不是*。如果没有提供特定的目标,就会泄露你发送到任何感兴趣的恶意站点的数据(由ZalemCitizen注释)。

引用:

一个插件助手的要点,允许父窗口调用子iframe窗口函数,反之亦然,但所有的调用都是异步的。

https://gist.github.com/clinuxrulz/77f341832c6025bf10f0b183ee85e072

这也可以跨原点工作,但只能调用从父窗口导出到iframe的函数,并且父窗口只能调用iframe导出的函数。