使用chrome扩展名覆盖用户定义的函数以使用本机函数

时间:2018-11-20 05:45:40

标签: javascript google-chrome-extension

我对JS相当陌生,并在其中使用Array.filter函数创建了chrome扩展,但是对于某些网站,网站所有者创建了自己的Array.filter函数,其行为与内置函数不同。有什么方法可以覆盖此用户定义的函数并获得此函数的本机行为。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

要保存原始的Array#filter方法,只需将其保存到一个变量中,然后在需要时使用call()使用它:

//Saving the original method
var ArrayFilter = Array.prototype.filter;
//Then whenever needing to use it, call it by using call()
var someArray = [1,2,3];
var filteredArray = ArrayFilter.call(someArray,function(){ /* your filter callback */ });

现在,您需要在创建修改后的filter()方法的脚本之前运行此程序。您必须通过更改加载内容脚本的时间来执行此操作,以便可以加载其他代码。这是通过在清单中设置run_at设置来完成的:

清单:

"content_scripts": [
  {
    "matches": ["http://*.example.com/*"],
    "run_at": "document_start",
    "js": ["contentScript.js"]
  }
],

contentScript.js

//injecting the script into the page
//or however you are currently doing it
var yourScript = document.createElement('script');
document.head.appendChild(yourScript);
yourScript.textContent = "/* your js code */";

答案 1 :(得分:0)

在页面脚本之前运行代码,并使用Object.defineProperty重新定义方法并禁止后续更改。您需要将该代码放入DOM script元素中,以便它使用文字字符串而不是src属性在页面上下文(more info)中运行,以确保其位于其他任何字符串之前页面脚本(more info)。

manifest.json:

"content_scripts": [{
  "matches": ["https://foo.bar/*"],
  "js": ["content.js"],
  "run_at": "document_start",
  "all_frames": true
}]

content.js:

const script = document.createElement("script");
script.textContent = `
  Object.defineProperty(Array.prototype, 'filter', {
    value: Array.prototype.filter,
    configurable: false,
    writable: false,
  });
`;
document.documentElement.appendChild(script);
script.remove();