如何使用 Greasemonkey 将 JavaScript 函数(与其他代码一起从远程文件加载)替换为我自己的实现?

How to replace a JavaScript function (which is loaded -among other code- from a remote file) with my own implementation using Greasemonkey?

有一个页面,例如。 http://somesite.com 运行位于路径中的一些 javascript 代码,例如 http://somesite.com/code.js

在该文件中 - 在其他代码中 - 有一个函数 (badFunction(x,y))。

我想更改其中一个局部变量的值,以使其与另一个(局部)变量(在 another 中使用)相等函数,也位于该远程 javascript 文件中)。

因此,基于这两个答案1 and 2 (i.e this userscript), 我尝试了以下简单的用户脚本,以便用我自己的实现替换整个 badFunction,但它不起作用(即我的 badFunction 未注入加载的 code.js - 我已经通过 Firefox 的调试器检查过了。

我试图用用户脚本完成的是,在加载 code.js 时,在达到 badFunction 定义时,注入我的函数实现,然后,让其余 code.js 继续正常加载。

我的用户脚本有什么问题?还是我的方法完全错误?

我不想给出上述远程 javascript 文件的实际 URL,因为它是 NSFW。

// ==UserScript==
// @name           @document-start Example
// @version        1
// @namespace      
// @include        http://somesite.com/*
// @run-at         document-start
// ==/UserScript==

var changed = 1; // script need to be edited with

window.addEventListener('beforescriptexecute', function(e) {

  ///for external script:   
    src = e.target.src;
    if (src.search(/code\.js/) == "badFunction") {
        changed--;
        e.preventDefault();
        e.stopPropagation();
        append(badFunction);
    };

    ///when done, remove the listener:
    if(changed == 0) window.removeEventListener(e.type, arguments.callee, true);

}, true);


////// append with new block function:
function append(s) {     
    document.head.appendChild(document.createElement('script'))
                          .innerHTML = s.toString().replace(/^function.*{|}$/g, '');
}

function badFunction(x, y)
{
 // my code
};

我没有你网站的源代码,所以我不知道 badFunction 是如何声明和调用的。但是请记住,如果在闭包内调用该函数,则需要将代码注入该闭包内的某处:

(function someClosure() {
  function hello() {
    // code
  }
  // hello is available
})();
// hello is not available

link 他们展示了如何修改现有的源代码

window.addEventListener('beforescriptexecute', function(e) {

    ///for external script:
    src = e.target.src;
    if (src.search(/bad\.js/) != -1) {
                changed++;
        e.preventDefault();
        e.stopPropagation();
        append(NewScript1);
    };
});

所以基本上你需要搜索你的功能代码并替换它。请记住,您可以使用 [\s\S]* link

在正则表达式中搜索换行符

阅读这两个答案后(我当然赞成):
How to overwrite a function using a userscript?
Stop execution of Javascript function (client side) or tweak it
(并且因为 badfunction 不是全局的,并且 code.js 立即触发并且是一个文件,而不是内联)
我得出的解决方案是:

  • 首先,获取脚本的副本并对其进行所需的更改。 保存在本地。
  • 然后使用 Adblock Plus 阻止加载那个 远程脚本文件。
  • 然后使用第二个link提供的脚本 将我修改的本地文件添加到页面。

    var scriptNode = document.createElement ("script");
    scriptNode.setAttribute ("src", "Point to your modified JS file here.");
    document.head.appendChild (scriptNode);