7

好的,所以我想要的是覆盖选项卡中已经存在的方法,我要使用的是默认警报功能。在 JS 函数中覆盖它会很容易。只需添加

window.alert = function(){ 
   //Do Something
}

但问题是当我尝试使用chrome.tabs.executeScript("window.alert = function() { };");它时它不起作用。我尝试通过在我想要覆盖该功能的选项卡中使用 Chrome 中的控制台手动执行此操作,我在日志中键入了该覆盖功能并按 Enter,然后完成,警报功能被覆盖,但我做不到这通过 Chrome 扩展程序。

当您添加 executeScript 时,它似乎创建了一个与选项卡 DOM 中的 JavaScript 不同的 Javascript,因为我可以使用选项卡 DOM 中已经存在的函数的名称创建函数。

有没有办法让 executeScript 在选项卡 DOM 中编写脚本,所以它实际上可以覆盖由页面生成的 .js 文件编写的任何函数?

谢谢!

4

1 回答 1

19

函数不作为 DOM 的一部分存在;相反,它们存在于包含 DOM的执行环境中。内容脚本(包括使用 运行的脚本executeScript)和实际网页共享相同的 DOM,但具有不同的执行环境。所以调用window.alert = function() {}只在内容脚本的执行环境中重写window.alert,而不是在实际页面的执行环境中。

到达实际页面的执行环境的典型方法是将<script>标签注入 DOM。这可以通过多种方式完成。一种方法是将 中的脚本列入白名单web_accessible_resource,并在文档中插入<script>引用该脚本的元素。所需的绝对 URL 可以通过chrome.extension.getURL.

var s = document.createElement("script");
s.src = chrome.extension.getURL("script_in_extension.js");
(document.head||document.documentElement).appendChild(s);

确保将脚本配置为"run_at": "document_start",以便在加载任何页面功能之前进行覆盖。

注意:您的操作可以通过页面轻松撤消:

window.alert = function(){ /*...*/ }; // Your overwrite
delete window.alert;                  // Run from the page/console/...
window.alert('Test?');                // Displays alert box.

如果无法删除被覆盖的函数至关重要,请使用Object.defineProperty定义不可变方法。有关更多详细信息,请参阅使用 Chrome 扩展程序停止执行函数

于 2012-08-23T16:22:40.073 回答