【问题标题】:Why is this code not working? I am creating a Firefox extension but the code is not running. But if I paste the code into the console it works为什么这段代码不起作用?我正在创建一个 Firefox 扩展,但代码没有运行。但是,如果我将代码粘贴到控制台中,它就可以工作
【发布时间】:2021-02-25 04:45:23
【问题描述】:

我做了一个 Firefox 扩展来获取所有请求的 url 并显示它们。但代码只有在我将其粘贴到控制台时才有效。

当扩展程序加载时它没有显示任何错误,它似乎只是不会运行

这是完整的代码

xhrScript.js

(function(){

    const proxiedOpen = XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function ( _, url) {
        this.__URL = url;
        return proxiedOpen.apply(this, arguments);
    };

    const proxiedSend = window.XMLHttpRequest.prototype.send;
    window.XMLHttpRequest.prototype.send = function () {
        const { protocol, host } = window.location;
        // showing only when it paste in console
        console.log("full request url ", `${protocol}//${host}${this.__URL}`);
        return proxiedSend.apply(this, [].slice.call(arguments));
    };

})();

// this works all times
document.body.style.border = "7px solid blue";

ma​​nifest.json

{
    "manifest_version": 2,
    "name": "XHR request urls",
    "version": "1.0",
    "description": "get all the request url's",

    "content_scripts": [
      {
        "matches": ["*://*/*"],
        "js": ["xhrScript.js"]
      }
    ]  
}

如您所见,最后一行是document.body.style.border = "7px solid blue";,每次都能正常工作。但是 XMLHttpRequest opensend 方法不起作用。仅当我将代码粘贴到控制台时才有效。

如果您想查看示例,可以尝试在 devTools 控制台中将 xhrScript.js 代码复制并粘贴到 https://reactjs.org(这是一个 SPA,因此很容易检查我想要的内容),然后查看所有请求。

我不知道为什么这段代码只有在控制台粘贴时才会运行

【问题讨论】:

    标签: javascript firefox xmlhttprequest firefox-addon firefox-addon-webextensions


    【解决方案1】:

    内容脚本在隔离的 JavaScript 环境中运行,这意味着 window 及其内容与页面隔离,因此当您修改它时,您只需修改内容脚本的版本。

    有两种解决方案:

    1. Firefox 特有的。

      使用wrappedJSObjectexportFunction 访问页面上下文(more info):

      const urls = new WeakMap();
      const origXhr = hookPagePrototype('XMLHttpRequest', {
        open(method, url) {
          urls.set(this, url);
          return origXhr.open.apply(this, arguments);
        },
        send() {
          console.log('Sending', new URL(urls.get(this), location).href);
          return origXhr.send.apply(this, arguments);
        },
      });
      
      function hookPagePrototype(protoName, funcs) {
        const proto = wrappedJSObject[protoName].prototype;
        const oldFuncs = {};
        for (const [name, fn] of Object.entries(funcs)) {
          oldFuncs[name] = exportFunction(proto[name], wrappedJSObject);
          proto[name] = exportFunction(fn, wrappedJSObject);
        }
        return oldFuncs;
      }
      
    2. Chrome 兼容。

      使用 DOM 脚本在页面上下文中运行代码:instruction

      它不适用于受严格的 Content-Security-Policy (CSP) 保护的页面,该 CSP 会阻止脚本执行,因此在为 Firefox 编写扩展时,我们应该改用 wrappedJSObject 方法。

    【讨论】:

    • 哇,它有效,我对制作浏览器扩展真的很陌生。这对我很有帮助,感谢分享文档
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    • 2020-05-16
    相关资源
    最近更新 更多