当前位置: 首页 > 知识库问答 >
问题:

从chrome扩展访问iframe

娄建义
2023-03-14

我正在开发一个chrome扩展,遇到了一个大问题。

$("#iframe1").contentWindow.document.execCommand("InsertHTML", false, 'test text');
TypeError: Cannot read property 'document' of undefined

奇怪的是,我可以访问iframe的html。因此,这段代码在chrome扩展中可以完美地工作:

$("#iframe1").contents().find('div').html('test')

我尝试将“all_frames”:true放入清单文件中,但没有成功:(

共有1个答案

路金鑫
2023-03-14

为了理解代码不能工作的原因,我包含了前面回答的一个片段:

内容脚本对页的全局窗口对象没有任何访问权限。对于内容脚本,适用以下内容:

  • 窗口变量不引用页的全局对象。相反,它指的是一个新的上下文,页面上的一个“层”。页面的DOM是完全可访问的。#执行环境
    null
// jQuery:
$("#iframe1").contents()[0].execCommand( ... );

// VanillaJS
document.getElementById("iframe1").contentDocument.execCommand( ... );

// "Unlock" contentWindow property by injecting code in context of page
var s = document.createElement('script');
s.textContent = 'document.getElementById("iframe1").contentWindow.document.execCommand( ... );';
document.head.appendChild(s);
if (window != top) {
    parent.postMessage({fromExtension:true}, '*');
    addEventListener('message', function(event) {
        if (event.data && event.data.inserHTML) {
            document.execCommand('insertHTML', false, event.data.insertHTML);
        }
    });
} else {
    var test_html = 'test string';
    // Explanation of injection at https://stackoverflow.com/a/9517879/938089 :
    // Run code in the context of the page, so that the `contentWindow`
    //  property becomes accessible
    var script = document.createElement('script');
    script.textContent = '(' + function(s_html) {
        addEventListener('message', function(event) {
            if (event.data.fromExtension === true) {
                var iframe = document.getElementById('iframe1');
                if (iframe && (iframe.contentWindow === event.source)) {
                    // Window recognised, post message back
                    iframe.contentWindow.postMessage({insertHTML: s_html}, '*');
                }
            }
        });
    } + ')(' + JSON.stringify(test_html) + ');';
    (document.head||document.documentElement).appendChild(script);
    script.parentNode.removeChild(script);
}

此演示仅用于教育目的,不要在真正的扩展中使用此演示。为什么?因为它使用postmessage来传递消息。客户端也可以生成这些事件,这会导致安全漏洞(XSS:任意HTML注入)。

PostMessage的替代方案是Chrome的消息API。有关演示,请参见以下答案。但是您将无法比较窗口对象。您所能做的就是依赖window.name属性。window.name属性自动设置为iframe的name属性的值(加载iframe时只设置一次)。

 类似资料:
  • 问题内容: 我正在做一个插件来对界面进行一些转换。我不断收到(典型的跨网站问题) 但作为扩展程序,它应该可以访问iframe的内容 … 没有人知道如何访问它的内容以便可以被捕获吗? 问题答案: 通常,没有直接访问其他来源对象的直接方法。如果要在不同框架中的内容脚本之间 安全地 通信,则必须将消息发送到后台页面,该页面又将消息发送回选项卡。 这是一个例子: 的一部分: : : 后台脚本“ bg.js

  • 问题内容: 是否可以从Java代码访问扩展功能? 我在Kotlin文件中定义了扩展功能。 (生成的)java类在哪里。现在,我想用普通的Java代码访问它: 但是,这不起作用。 IDE无法识别该方法,并且编译失败。 起作用的是与kotlin的静态函数一起使用: 通过使用我的IDE似乎已正确配置。 我从kotlin文档中搜索了整个Java互操作文件,并且在谷歌上搜索了很多,但是找不到。 我究竟做错了

  • 我在Kotlin文件中定义了扩展函数。 其中是(生成的)java类。现在,我想用正常的java代码访问它: 然而,那是行不通的。IDE将无法识别方法,编译失败。

  • 我构建了一个chrome扩展作为独立的iframe,它通过脚本注入网站。用户可以通过快捷方式访问扩展。因此,如果用户输入快捷方式,就会弹出iframe。在iframe内部是一个输入字段,当用户输入快捷方式时,我希望聚焦该字段。 我的第一个想法是做这样的事情: 但这确实导致了以下错误:

  • Tweetmeme Chrome 扩展其实就是一个精简版的 TweetMeme 按钮,其作用就是让你“随时随地”都可以向你的关注者分享你正在浏览的网页(“随时随地”加引号是因为在天朝该服务不可用),简单点说就是一个 retweet 按钮。通过 Tweetmeme Chrome 扩展分享出的网址会采用 retwt.me 短网址服务进行缩短,对于身在墙外或者随时都在翻墙状态的用户来说非常实用。 安装

  • 我知道如何在selenium webdriver中加载chrome扩展。但是我没有看到任何描述如何从Selenium运行chrome扩展的帖子/博客。< br> 我需要明确地让chrome扩展运行/让它从selenium执行它的功能。比如我想用Selenium Webdriver的这个扩展清除Chrome浏览器的缓存。< br> 我可以先做吗?或者Selenium WebDriver是否只帮助我将