javascript - 用 mozilla addon SDK 替换完整的 HTML

标签 javascript firefox-addon-sdk

有没有办法替换完整的 HTML,并使用 mozilla addon SDK 添加额外的 javascript 文件?

对于 chrome,可以通过在“document_start”处运行脚本、停止窗口并用 XHR 响应替换完整的 HTML 来完成。我不明白为什么这么复杂,但我可以忍受。据我了解,addon SDK 有一个 page-mod 模块,该模块是关于“在 URL 与给定模式匹配的网页上下文中运行脚本”。所以理论上这应该通过 page-mod 模块来完成,但我没有找到任何完全覆盖整个 HTML 的示例。理论上,window.stop 和替换完整的 HTML 也应该在这里工作,但我无法从网页(前端)的上下文访问插件(后端)文件。对于 chrome,这是通过 list 中的“web_accessible_resources”和 chrome.extension.getURL 完成的。通过 firefox,我无法通过前端使用与插件 SDK 相关的任何内容,因此 self.data.url 不起作用...

最佳答案

我尝试以这种方式发送文件内容(因为前端的 Firefox 拒绝了插件文件访问):

index.js

var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;

pageMod.PageMod({
    include: ["http://example.com/", "http://example.com/index.html"],
    contentScriptFile: "./inject.js",
    contentScriptWhen: "start",
    onAttach: function (worker){
        console.log("injector attached");
        worker.port.emit("inject", {
            "index.html": data.load("client/index.html"),
            "main.js": data.load("client/main.js")
        });
    }
});

注入(inject).js

!function () {
    self.port.on("inject", function (files) {
        console.log("injector trigger");
        if (typeof hasRun == 'undefined') {
            console.log("injecting");
            hasRun = true;
            window.stop();
            var html = files["index.html"].replace("<script src=\"./main.js\"></script>", "<script>"+files["main.js"]+"</script>");
            document.documentElement.innerHTML = html;
        }
    });
}();

如果我用 hello world 替换 HTML,那么它就可以工作。因此 HTML 似乎无效,但我没有收到错误消息,并且控制台显示一个空的 HTML 骨架(我得到一个空页面)。相同的index.html和main.js代码通过chrome插件工作,我想在firefox中使用它。 Chrome 插件唯一额外的事情是,某些 js 文件被取消,因此在停止窗口之前它们肯定不会加载。我尝试做同样的事情,但也许没有成功,我不知道。

index.js

let { Ci, Cu } = require('chrome');

Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");

var observer = {
    QueryInterface: XPCOMUtils.generateQI([
        Ci.nsIObserver,
        Ci.nsISupportsWeakReference
    ]),

    observe: function (subject, topic, data) {
        if (topic == "http-on-opening-request" &&
            subject instanceof Ci.nsIHttpChannel) {
            var uri = subject.URI;
            if (uri.host == "example.com" && /some\.js/.test(uri.path))
                subject.cancel();
        }
    }
};

Services.obs.addObserver(observer, "http-on-opening-request", true);

subject.cancel() 由 some.js 文件运行。如果我添加日志记录:

            console.log("cancelling", uri.path);
            subject.cancel();
            console.log("cancelled");

然后控制台中不会出现“已取消”,只会出现“正在取消,/some.js”。我不知道这是否正常,但我没有收到错误消息。

通过常规 HTML 网页尝试此操作

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <script>
    //<![CDATA[
        !function (){
            window.stop();
            var html = '<!DOCTYPE html>\n<html>\n<head>\n    <meta charset="utf-8">\n</head>\n<body>\n  <script>console.log("loaded");</script>\ntext\n</body>\n</html>';
            document.documentElement.innerHTML = html;
        }();
    //]]>
    </script>
</body>
</html>

我遇到了一个未终止的字符串文字语法错误,这更有趣。我想如果注入(inject)器代码包含 javascript,它就无法正常工作,所以我认为这不是一个与插件相关的问题。如果我使用 <\/script>那么就可以了,但是console.log("loaded");脚本不运行。通过chrome它确实可以运行,所以这就是我认为的问题。

我将 jquery 添加到“contentScriptFile”并使用 $("html").html(html)相反 document.documentElement.innerHTML = html 。它现在运行脚本,但仍然无法正常工作。

通过 cancel() 添加了一些修复:

let { Ci, Cu, Cr } = require('chrome');
//...
subject.cancel(Cr.NS_BINDING_ABORTED);

cancel 似乎有一个必需的状态参数,但当它没有获取它时,它会默默地失败。现在取消文件也可以了,但插件仍然在某个地方失败。 :S

我认为我编写的注入(inject)器工作得很好,问题出在注入(inject)的 HTML 和 js 文件上。我不打算调试它们(因为 $.load 使用 eval,所以这会很困难),我将代码发送给 chrome 插件开发人员,也许他们可以以某种方式修复它。

关于javascript - 用 mozilla addon SDK 替换完整的 HTML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30931703/

相关文章:

javascript - 未捕获的类型错误 : undefined is not a function (on video pause function)

javascript - 放大的弹出窗口安装/初始化

bash - 从另一个目录获取 bash 文件并返回当前目录的别名

javascript - Firefox 插件中有多个 js 文件可以有 require 方法吗?

firefox-addon - 如何在 Firefox 插件中以编程方式打开开发者工具的控制台?

javascript - 如何保护 HTML5+PhoneGap 移动应用程序中的数据?

javascript - 使用服务器端包含检查当前页面是否是主页--如果是,则显示脚本标签

javascript - 如何更改标记的颜色

firefox-addon - Firefox 扩展内容脚本调用/生命周期

javascript - 如何在内容脚本和面板之间进行通信