【问题标题】:Use content script to define global variables使用内容脚本定义全局变量
【发布时间】:2014-06-04 19:13:37
【问题描述】:

我正在创建一个 Firefox 扩展程序,我希望它的一个功能是用户能够将脚本或样式表注入特定网站,就像 Greasemonkey 一样(除了这仅适用于一个网站) .我正在为要使用的脚本添加一些功能,我打算将这些功能从内容脚本添加到主(不安全)窗口中。在MDN blog 上,它说他们已经改变了它的实现方式,所以我按照帖子中的建议将我的代码基于新的实现,所以这就是我所拥有的:

var $jq = jQuery.noConflict();//Yes, I am also injecting jQuery at the same time
console.log("created jquery object"); //This works
exportFunction($jq, unsafeWindow, {defineAs: "$jq"});
console.log("This will never be called");

但是脚本的执行刚刚停止,并且在控制台中打印Message: TypeError: window is null。 我主要在 Firefox 28 中进行测试(我现在似乎无法让 Firefox for Ubuntu 进行更新,而且一大堆问题迫使我为此在 VM 中使用 Ubuntu),但在 Nightly 31a1(Win7 ) 没有注入任何东西,包括硬编码样式(适用于 FF28),所以我必须在某个时候弄清楚这一点。 (PageMod 代码在这里:

var lttWorker = sdk.pageMod.PageMod({
    include:["*"],
    /*contentScriptFile: [sdk.data.url("jquery.large.js"), sdk.data.url("scripts/bootstrapper.js")],
    contentScriptWhen: "ready",*/ //This is commented to test whether it was an issue with the script. It's not.
    contentStyle: "#header_bar{background-color:green;}", //This is injected in FF28 but not 31
    attachTo: ["existing", "top"],
    onAttach: function(){desktopNotifications({title:"attached content worker", text:"The content worker has been successfully attached"})} //This is called in FF28 but not 31
});
lttWorker.on("error", function(){callError("pageWorker failed");}); //This never gets called. Ever.

如果有人感兴趣)

编辑:我现在已经在 Firefox 30b 上尝试过,但仍然存在很多问题,尽管它们似乎与 FF28 和 31 略有不同...

【问题讨论】:

标签: javascript firefox-addon firefox-addon-sdk content-script


【解决方案1】:

首先:Firefox 30 及更高版本支持这些新功能。请参阅@canuckistani 答案。

exportFunction API 过于受限,无法实际注入像 jQuery 之类的东西,其中所有复杂对象都是或包含 DOM 节点。应用于参数的结构化克隆算法根本无法实现。 API 旨在作为插件与页面双向通信的一种方式,而不是注入复杂的库。

您最好的选择实际上是使用 DOM API 创建一个脚本标签并将 jQuery 放在那里。

【讨论】:

  • 我确实尝试过,但由于某种原因它不起作用。这就是我所拥有的:$jq("body").append($jq("<script>", { src: "https://code.jquery.com/jquery-2.1.1.min.js" })).append($jq("<script>").html("var $jq = jQuery.noConflict();$jq('body').hide()"));,但虽然身体被隐藏(所以应该定义$jq),它不是根据萤火虫全局定义的。我必须使用 noConflict()。
  • 看起来很理智,除了远程代码注入(如果是 jquery,你应该注入本地发送的副本)......我可能会稍后再看......
  • 我只使用 jQuery 的远程副本以使其更易于测试,否则我不得不将资源 URL 发送到脚本。我会在生产代码中这样做。此外,如果我将脚本标签中完全相同的代码放入 FB 控制台,它就可以正常工作。
猜你喜欢
  • 2015-08-22
  • 1970-01-01
  • 2016-03-15
  • 1970-01-01
  • 2016-10-06
  • 2016-03-03
  • 2022-01-21
  • 2016-09-23
相关资源
最近更新 更多