【问题标题】:ContentScript in Firefox extension without using the Add-On SDK不使用附加 SDK 的 Firefox 扩展中的 ContentScript
【发布时间】:2014-06-13 09:35:44
【问题描述】:

有没有一种简单的方法可以为简单的内容脚本创建 Firefox 扩展而无需使用 Add-On SDK 和 PageMod?安装 Python 和 SDK、学习如何使用 SDK 和 API 以及添加不必要的膨胀和抽象层,仅仅为了执行一个简单的内容脚本,这似乎有点过头了。

我已经尝试使用 XUL 浏览器覆盖并在其中注入脚本,但是将所有内容注入 browser.xul 上下文而不是 document.body 也会增加很多复杂性...

那么在 html 文档而不是 XUL 文档中注入一些脚本和 css 文件的最简单、轻量级的方法是什么?

【问题讨论】:

    标签: javascript firefox firefox-addon content-script


    【解决方案1】:

    您的猜测过于宽泛,因此我不会详细讨论所有内容,而是提供一个总体概述。

    Easy 可能言过其实,但 SDK 内容脚本(实际上也包括模块)、Greasemonkey/Scriptish 以及其他所有类似于内容脚本的内容都在内部使用 Sandbox。甚至 bootstrap.js 在无需重启的插件中也会在沙箱中执行。

    基本思路如下:

    1. 获取对您要附加的内容窗口的引用。
    2. 选择脚本应在其下运行的“主体”。主体本质上是定义相同来源的安全上下文/策略。非特权内容脚本通常会使用内容窗口本身(这也是一个主体),而特权脚本(Chrome 访问 Components)脚本将使用系统主体。
    3. 选择是否需要 XRay 包装器。文档会告诉您更多相关信息。
    4. 选择沙盒原型(“全局”或顶​​级 this)。通常对于内容脚本内容,您会选择内容窗口。
    5. 创建Sandbox
    6. 将您的内容脚本可能需要的任何内容添加到沙盒中。
    7. 通过evalInSandboxsubscript loader 执行脚本。

    这是一个有限的示例,将非特权内容脚本添加到窗口:

    // 1. get the content window, e.g. the currently selected tab window
    var contentWindow = gBrowser.contentWindow;
    // 2. Choose the principal, e.g. just use the content window again
    var principal = contentWindow;
    // 3. We want XRay wrappers, to keep our content script and the actual
    // page scripts in their own corners.
    var wantXrays = true;
    // 4. Our prototype will be the window
    var sbProto = contentWindow;
    // 5. Putting it all together to create a sandbox
    var sandbox = Cu.Sandbox(principal, {
      sandboxPrototype: sbProto,
      wantXrays: wantXrays
    });
    // 6. Adding a random helper function (e.g.)
    sandbox.getRandomInt = function (min, max) {
      return Math.floor(Math.random() * (max - min + 1)) + min;
    };
    // 7. Execute some content script, aka. the stupid example.
    try {
      var execute = function() {
        var demo1 = document.querySelector('title').textContent;
        var demo2 = getRandomInt(1, 1000);
        alert(demo1 + " " + demo2);
      }
      Cu.evalInSandbox(
        "(" + execute.toSource() + ")()",
        sandbox
      );
    } catch(ex) {
      console.error(ex);
    }
    

    PS:此示例将在 Scratchpad with Environment/Browser 中逐字运行。

    关于风格:

    做 SDK 做的事情,我猜是简化的:

    var wu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
             getInterface(Ci.nsIDOMWindowUtils);
    var uri = Services.io.newURI(
      "chrome://myaddon/style/content-style.css",
      null,
      null);
    wu.loadSheet(uri, wu.USER_SHEET);
    

    【讨论】:

    • 谢谢,这帮助很大。您能否提供有关 loadSheet 方法的更多信息?在文档中找到一些东西真是太痛苦了......我找不到任何东西,并且 loadSheet 在第一个文档加载后给了我废话:组件返回失败代码:0x80070057 (NS_ERROR_ILLEGAL_VALUE) [nsIDOMWindowUtils.loadSheet]。
    • 没关系,我在错误的窗口上加载了工作表... DOH!如果我能找到文档还是会很好:)
    • 要将您的示例用于沙箱,我只需在 XUL 中加载脚本,对吗? SDK 通过 contentScriptFile 加载它们,但 XUL 只会使用常规的 script 标签。
    猜你喜欢
    • 2014-02-26
    • 1970-01-01
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多