是否可以注入一个覆盖DOM中存在的javascript代码?(例如默认警报功能)

Gre*_*ego 5 google-chrome google-chrome-extension

好的,所以我想要的是覆盖选项卡中已经存在的方法,我将使用的是默认的警报功能.在JS函数中覆盖它会非常容易.加上

window.alert = function(){ 
   //Do Something
}
Run Code Online (Sandbox Code Playgroud)

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

当您添加executeScript时,它似乎创建了一个除了选项卡DOM内部的Javascript之外的Javascript,因为我可以创建具有选项卡DOM中已存在的函数名称的函数.

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

谢谢!

aps*_*ers 18

函数不作为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 Code Online (Sandbox Code Playgroud)

确保脚本配置为"run_at": "document_start",以便在加载任何页面函数之前进行覆盖.

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

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

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