为何无法从父页面访问iframe中的test函数?
问题原因与解决方案
核心原因
当iframe的src为Blob URL时,浏览器会将其视为独立的跨域源——哪怕Blob内容是你本地生成的,父页面与iframe之间仍会受同源策略限制,无法直接访问对方的全局对象和函数,这就是调用test()时提示“不是函数”的根本原因。
解决方法
方法1:使用postMessage跨源通信
这是跨源iframe交互的标准方案,无需突破同源限制:
- 在iframe的脚本中监听
message事件:
<script> function test(){alert("test")}; test(); // 监听父页面的调用指令 window.addEventListener('message', function(e) { if (e.data === 'invokeTest') { test(); } }); </script>
- 父页面通过
postMessage触发函数:
window.frames['blob-src-test'].contentWindow.postMessage('invokeTest', '*');
注意:参数
'*'允许任意源通信,生产环境建议替换为具体的目标源,提升安全性。
方法2:替换Blob URL为同源加载方式(场景允许时)
如果不需要用Blob承载内容,可改用同源HTML文件或data:text/html协议加载,这样就能直接访问iframe的全局函数:
var template = [ '<h1>', variables.title, '</h1>', '<img width="80%" src="', variables.image, '">', '<script>function test(){alert("test")};test()<\/script>' ].join(''); var iframe = document.getElementById('blob-src-test'); // 用data协议替代Blob URL iframe.src = 'data:text/html;charset=utf-8,' + encodeURIComponent(template); // 加载完成后调用函数 iframe.onload = function() { this.contentWindow.test(); };
方法3:同源场景下直接注入脚本
若iframe为同源(非Blob URL),可在iframe加载完成后,直接向其上下文注入脚本:
var iframe = window.frames['blob-src-test']; iframe.onload = function() { var script = iframe.contentDocument.createElement('script'); script.textContent = 'function test(){alert("test")};test()'; iframe.contentDocument.body.appendChild(script); // 注入完成后直接调用 iframe.contentWindow.test(); };
内容的提问来源于stack exchange,提问作者user310291
相关产品推荐
相关产品推荐

