用Mozilla插件SDK替换完整的HTML [英] Replace complete HTML by mozilla addon SDK

查看:124
本文介绍了用Mozilla插件SDK替换完整的HTML的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用mozilla插件SDK替换完整的HTML并添加其他javascript文件?

Is there a way to replace the complete HTML, and add additional javascript files with mozilla addon SDK?

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

With chrome it can be done by running the script at "document_start", stop the window and replace the complete HTML with an XHR response. I don't understand why is this so complicated, but I can live with that. As far as I understand the addon SDK has a page-mod module, which is about "running scripts in the context of web pages whose URL matches a given pattern." So in theory this should be done with the page-mod module, but I did not find any example which completely overrides the whole HTML. In theory the window.stop and replacing the complete HTML should work here too, but I am not able to access the addon (backend) files from the context of the webpage (frontend). By chrome this is done via "web_accessible_resources" in the manifest and chrome.extension.getURL. By firefox I cannot use anything related to the addon SDK by frontend, so self.data.url does not work...

推荐答案

我试图用这种方式发送文件内容(因为从前端开始,Firefox拒绝了附加文件的访问):

I tried to send the file contents this way (since the addon file access was denied by firefox from the frontend):

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

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;
        }
    });
}();

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

If I replace the HTML with hello world, then it works. So the HTML appears to be invalid, but I got no error message and the console shows an empty HTML skeleton (I got an empty page). The same index.html and main.js code works by a chrome plugin, which I want to use in firefox. The only extra thing by the chrome plugin, that some js file is cancelled out, so they are surely not loaded before stopping the window. I tried to do the same, but maybe it did not work, I don't know.

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文件运行.如果我添加日志记录:

The subject.cancel() runs by the some.js file. If I add logging:

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

然后,"cancelled"将不会出现在控制台中,只会显示"cancelling/some.js".我不知道这是否正常,但没有错误消息.

Then the "cancelled" does not appear in the console, just the "cancelling, /some.js". I don't know whether this is normal, but I got no error message.

通过在常规HTML网页上进行尝试

By trying this with a regular HTML webpage

<!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>

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

I got an unterminated string literal syntax error, which is even funnier. I guess somehow the injector code does not work properly if it contains javascript, so this is not an addon related issue I think. If I use <\/script> then it is okay, but the console.log("loaded"); script does not run. By chrome it does run, so that is the problem I think.

我将jquery添加到了"contentScriptFile",并使用了$("html").html(html)而不是document.documentElement.innerHTML = html.它现在可以运行脚本,但仍无法正常工作.

I added jquery to the "contentScriptFile" and used $("html").html(html) instead document.documentElement.innerHTML = html. It runs the scripts now, but still does not work properly.

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

Added some fix by cancel():

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

取消似乎具有必需的状态参数,但是如果没有获取,它将自动失败.现在取消文件也可以,但是插件仍然在某处失败. :S

cancel appears to have a required status parameter, but it silently fails when it does not get it. Now cancelling files works too, but the plugin still fails somewhere. :S

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

I think the injector I wrote works perfectly, and the problem is with the injected HTML and js files. I don't intend to debug them (since $.load uses eval, so it would be very hard), I sent the code to the chrome plugin developers, maybe they can fix it somehow.

这篇关于用Mozilla插件SDK替换完整的HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆