【问题标题】:Remove specific javascript function with Greasemonkey使用 Greasemonkey 删除特定的 javascript 函数
【发布时间】:2020-03-06 12:43:54
【问题描述】:

我访问的网站在 HTML 的头部有一个 javascript 文件

<script>(function(d){var config={kitId:'gpn1wjb',scriptTimeout:3000,async:true},h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='//use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)})(document);</script>

如何使用 Greasemonkey 禁用/删除/替换此功能?

【问题讨论】:

    标签: javascript greasemonkey


    【解决方案1】:

    没有标准的方法来处理这个问题。您要禁用的功能会在浏览器读取 HTML 的那部分后立即执行,这意味着即使您在文档加载开始时运行用户脚本(使用 @run-at document-start),也无法从 tampermonkey 中删除脚本节点。

    您可以尝试利用他们调用setTimeout 的事实。这个想法是在他们调用它的那一刻抛出一个错误,这样他们的代码 sn-p 就不能正常运行。

    代码应如下所示。确保您访问的是未沙箱化的 window 对象。

    const oldSetTimeout = window.setTimeout;
    // replace setTimeout with our hacked version
    window.setTimeout = newSetTimeout;
    /**
     *
     * @param {function} cb
     * @param {number} delay
     */
    function newSetTimeout(cb, delay) {
        // Check if callback contains string we know from the sourcecode
        if (cb && cb.toString().indexOf("bwf-loading")!=-1) {
            // misdeed done, restore normal setTimeout
            window.setTimeout = oldSetTimeout;
            throw new Error("Failing set timeout to kill unwanted script.");
        }
        // otherwise act as normal setTimeout
        else {
            return oldSetTimeout.call(window, arguments);
        }
    }
    

    【讨论】:

    • 您是否确保代码在文档开始时正确执行?有一个greasemonkey设置。
    【解决方案2】:

    采用example from Tomas 并将其更新为与 Greasemonkey v4 一起使用,主要变化是您需要跨上下文导出函数。此示例更改了适合我的用例的 document.body.appendChild 函数,但我还有一些其他函数也使用类似的模式。

    const overwriteAC = function(){
      // despite comments in https://stackoverflow.com/questions/48122766/function-not-defined-or-permission-denied-to-access-object-in-greasemonkey/48194770
      // `unsafeWindow.[...]` does not seem to be necessary here
      // however, on other (?) functions e.g. `document.createElement` you will need to
      // use `.bind()` as per comments here
      // https://stackoverflow.com/a/24339478/2640621
      // e.g. `const oldCreateElement = document.createElement.bind(document);`
      const oldAC = document.body.appendChild;
      const newAC = function(node) {
        if (node && "src" in node && node.src.includes("recaptcha")) {
          console.log(`Blocking ${node.src}.`);
          node.src = "";
          node.text = "";
          // `functions` returns a list, `appendChild` only takes one argument so we just pass `node` here instead
          // the first argument to `.call()` changes depending on which function you're modifying
          // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call#parameters
          oldAC.call(document.body, node);
        } else {
          oldAC.call(document.body, node);
        };
      };
      // as per https://www.greasespot.net/2017/09/greasemonkey-4-for-script-authors.html
      // and https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Sharing_objects_with_page_scripts#exportfunction
      // this is required for the page script's scope to access the `newAC()` function
      exportFunction(newAC, document.body, {defineAs:'appendChild'});
    };
    
    // this was needed for `appendChild` as `document.body` does not exist when this script starts
    // not necessarily required for other functions, so you could call your `overwriteFoobar()` function
    // from the root of the script without using `MutationObserver`
    // https://stackoverflow.com/a/26324641/2640621
    var observer = new MutationObserver(function() {
      if (document.body) {
        overwriteAC();
        observer.disconnect();
      }
    });
    observer.observe(document.documentElement, {childList: true});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      • 2019-03-10
      • 2011-06-27
      相关资源
      最近更新 更多