【问题标题】:contentWindow is undefined for dynamically loaded iframe on Chrome对于 Chrome 上动态加载的 iframe,contentWindow 未定义
【发布时间】:2012-01-09 04:01:26
【问题描述】:

我正在编写一个 Chrome 扩展程序(在这种情况下不应该(?)重要的事实)。

当用户选择文本时,我正在动态添加 iframe,如下所示:

var myframe = '<div id="modal-from-dom" class="modal hide fade" style="width: 673px;">' +
                   '<div class="modal-body">' +
                   '<iframe id="iFrameID" style="border: 0px;"   src="http://www.example.com/" height="240px" width="638px"></iframe>' +
                   '</div>' +
                   '</div>';

$('body').append(myframe);

然后我继续搜索 iFrame,直到返回一个非空对象。然后我尝试访问最终未定义的contentWindow 属性(尽管src 等其他属性很好):

$('#iFrameID').prop('contentWindow'); // undefined

提前感谢您提出的任何想法。

P.S.:最终目标是获取 iframe 内元素的大小,以便我可以使用 postMessage 适当调整 iframe 主机的大小。

【问题讨论】:

  • 我认为您应该在myframe 的HTML 中插入一个脚本,该脚本将通过postMessage 将元素的大小发送到其父框架。
  • @check_ca,是的,这将是我的工作。

标签: javascript google-chrome iframe google-chrome-extension


【解决方案1】:

这是 Chrome 扩展程序的一个已知问题。

iFrame 的 contentWindowcontentDocument 属性为 undefinedwindow.frames 也是空的。结果是您不能使用postMessage 向下通信到 iFrame。

http://code.google.com/p/chromium/issues/detail?id=20773

您可以通过使用与 iframe 的 src 匹配的内容脚本来解决此问题,以访问框架的 window,从而使您能够使用 postMessage API 与其通信。

这是一个示例,它获取所有 chrome 消息并将它们作为 iframe 中的消息事件触发:

chrome.extension.onMessage.addListener = function(request, sender, sendResponse){
  // Pass on some messages context for local execution
  window.postMessage(request, "*");
}

【讨论】:

    【解决方案2】:

    我建议为要显示的 url 制作一个 ajax GET,获取 html 响应,添加一个脚本标签,该标签将使用 postMessage 与您的父框架(您的扩展代码),然后将 iframe 的 src 设置为数据 url base64 编码数据。阅读一些代码更容易:

    var iFrameID = $(document.getElementById('iFrameID')); //This is very efficient.
    
    $.get('http://www.example.com', function(response) {
      postMessager = '<script>'+
        'window.postMessage ... '+ 
    

    参考https://developer.mozilla.org/en/DOM/window.postMessage这里

        '</script>'
      iFrameID.src = 'data:text/html;base64,' + utf8_to_b64(postMessager + response));
    });
    

    在哪里

    function utf8_to_b64( str ) {
        return window.btoa(unescape(encodeURIComponent( str )));
    }
    
    function b64_to_utf8( str ) {
        return decodeURIComponent(escape(window.atob( str )));
    }
    

    在您的扩展代码中,您当然还需要 postMessage 代码。我知道这不是最完整的信息和代码,但我希望它能为您指明一个可靠的方向。将 innerHTML 插入没有 src 属性的 iframe 时要小心,因为不会运行 javascript。如果您想要 iframe 互联网上的任何常规页面,我有一些东西可以完成,您可以给我发消息。

    【讨论】:

    • 在内容脚本中,您可以毫不费力地对任何域进行 ajax。
    猜你喜欢
    • 1970-01-01
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2017-01-11
    • 2013-10-31
    相关资源
    最近更新 更多