JS操作iframe兼容主流浏览器的解决方案

作者:页面旅途时间:2026-10-27 12:40:15浏览:279

在本地文件系统或不同源环境下,直接通过window.parent调用父页面方法常因安全策略被Chrome拦截。本文通过对比传统调用方式与HTML5 postMessage机制,提供一套兼容方案:优先尝试直接调用,失败时自动降级使用postMessage发送指令,确保在各类浏览器中均能实现父子页面间函数调用的稳定运行。

iframe跨域调用背景与问题

在项目开发过程中,经常需要处理iframe内部页面与父页面之间的交互,例如子页面调用父页面的特定函数。为了验证这一逻辑,作者编写了两个简单的HTML测试页面。然而,使用网络上常见的通用方法时,在Google Chrome浏览器中却频繁报错,导致功能无法正常运行。


以下是父页面parent.html的代码示例:


具体代码实现如下:

 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<script src="jquery-1.10.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
function ParentFunction() {
alert('ParentFunction');
} 
</script></head>
<body>
<input type="button" id="btnCancel" class="button" value="测试" />
<iframe id="FRMdetail" name="FRMdetail" frameborder="0" src='child.html' style="width:100%;height:100%;" ></iframe>
</body>
</html>

以下是子页面child.html的代码示例:


具体代码实现如下:

 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<script src="jquery-1.10.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnTest").click(function (e) {
var t=window.parent;
t.ParentFunction();
}); 
}) 
</script></head>
<body>
<input type="button" id="btnTest" class="button" value="应该获取的值" />rrr
</body>
</html>

传统方法的浏览器兼容性问题

网络上流传的通用方法var t=window.parent; t.ParentFunction();在IE浏览器中可以正常调用,但在Chrome浏览器中却会抛出如下错误提示:


Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.


经过长时间的搜索与排查,发现网上现有的解决方案大多基于较早的版本,已不再适用,且许多内容缺乏实际测试验证。经过自主摸索发现,Chrome浏览器其实支持上述方法,但存在一个奇怪的限制:该方法仅在页面发布到服务器后有效;如果在本地文件系统中直接打开HTML文件,则会触发前述的安全错误。


基于postMessage的兼容解决方案

此外,HTML5提供了一种名为postMessage的标准通信机制。基于此机制对代码进行改写后,最终实现如下:


父页面parent.html的优化代码如下:


具体代码实现如下:

 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<script src="jquery-1.10.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
this.ParentFunction= function() {//和注释掉的方法是一样的,也就是说加不加this都是一样的,因为此处的this就是windows
alert('ParentFunction');
} 
// function ParentFunction() {
// alert('ParentFunction');
// } 
function receiveMessage(e) {
var data = e.data;
if(data=="ParentFunction")
{ 
ParentFunction() ;
} 
} 
if (typeof window.addEventListener != 'undefined') {//使用html5 的postMessage必须处理的
window.addEventListener('message', receiveMessage, false);
} else if (typeof window.attachEvent != 'undefined') {
window.attachEvent('onmessage', receiveMessage);
} 
</script></head>
<body>
<input type="button" id="btnCancel" class="button" value="测试" />
<iframe id="FRMdetail" name="FRMdetail" frameborder="0" src='child.html' style="width:100%;height:100%;" ></iframe>
</body>
</html>

子页面child.html的优化代码如下:


具体代码实现如下:

 
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>
</title>
<script src="jquery-1.10.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#btnTest").click(function (e) {
var t=window.parent;
if(!t.ParentFunction)//在不支持时,使用html5 的postMessage方法
{ 
t.postMessage("ParentFunction", '*');
} 
else
{ 
t.ParentFunction();
} 
}); 
}) 
</script></head>
<body>
<input type="button" id="btnTest" class="button" value="应该获取的值" />rrr
</body>
</html>

经过上述改写后,即使在本地文件系统中打开页面时仍可能遇到之前的安全错误提示,但实际调用的父页面方法依然能够成功执行,达到了预期的功能目标,不影响正常使用。

作者最新文章