Edge & IE:创建 iframe 并访问 window 对象后权限被拒绝

Edge & IE: Permission Denied after creating an iframe and accessing window object

我在脚本中创建 iframe 时有一些延迟 (setTimeout) 并尝试访问 window 对象时,在 Edge 和 IE 上出现 "Permission Denied" 错误。

它适用于所有其他浏览器,并且在 IE 和 Edge 上无延迟。

<script>
    function createIframe(win) {
        console.log('foo', win.foo);
        var width = 300;
        var height = 250;
        var id = 'ifr';
        var src = '';
        var iframeTemplate = '<iframe id="'+id+'" src="'+src+'" width="'+width+'" height="'+
            height+'"  marginheight="0" marginwidth="0" scrolling="NO" frameborder="0"></iframe>';
        win.document.write(iframeTemplate);
        var iframe = win.document.getElementById(id);
        console.log('foo', win.foo);
        if (iframe) {
            var doc = iframe.contentWindow.document;
            doc.write('<html><head></head><body><script>console.log("foo on parent", window.parent.foo);</scr'+ 'ipt></body></html>');
            doc.close();
        } else {
            console.log('Failed to create an iframe');
        }
    }
    window.foo = 'bar';
    setTimeout(function() {
        createIframe(window);
    }, 3000);

</script>

此代码应打印:

foo bar
foo bar
foo on parent bar

但是它在 Edge 和 IE 上的第二个 console.log 上抛出错误 "Permission Denied"。

没有 setTimeout 也能正常工作。

如果我删除第二个 console.log,并从 iframe 中访问 window.parent.foo,它在 Edge 和 IE 上是未定义的

片段:

不适用于 Edge 和 IE:https://jsfiddle.net/vo2yrjft/

适用于 Edge 和 IE:https://jsfiddle.net/6cbfk1yr/

有什么解决方法吗?

document.write是一个"bad practice",会屏蔽该页面,具体可以参考this thread

作为解决方法,您可以使用 createElement('iframe') 创建 iframe,然后使用 appendChild() 插入元素。下面是示例代码,它可以运行很好地在IE & Edge:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    <script>
        function prepareFrame(win) {
            console.log('foo', win.foo);
            var id = 'ifr';
            var ifrm = document.createElement('iframe');
            ifrm.setAttribute('src', '');
            ifrm.setAttribute('id', id);
            ifrm.setAttribute('marginheight', 0);
            ifrm.setAttribute('marginwidth', 0);
            ifrm.setAttribute('scrolling', 'NO');
            ifrm.setAttribute('frameborder', 0);
            ifrm.style.width = '300px';
            ifrm.style.height = '250px';
            document.body.appendChild(ifrm);
            var iframe = win.document.getElementById(id);
            console.log('foo', win.foo);
            if (iframe) {
                var doc = iframe.contentWindow.document;
                doc.write('<html><head></head><body><script>console.log("foo on parent", window.parent.foo);</scr' + 'ipt></body></html>');
                doc.close();
            } else {
                console.log('Failed to create an iframe');
            }
        }
            window.foo = 'bar';
            setTimeout(function() {
                prepareFrame(window);
            }, 3000);
    </script>
</body>
</html>