Framescripts are not webpages 并且不提供对 jquery 期望存在的大多数全局变量的访问,例如XHR、文档和窗口本身等。
即使您以一种看起来像窗口环境的方式操纵变量,这仍然会产生很大的问题,因为框架脚本的生命周期超出了 DOM 窗口的生命周期,即它的存在与选项卡相关联,而不是到选项卡的各个页面。 Jquery 被设计为只与页面一样长。
第三个问题是安全性,框架脚本使用chrome/system privileges 运行,如果您直接从框架脚本运行它,jquery 也会如此。 Jquery 并非设计为具有安全意识,因为它通常受网站同源策略的约束。事件处理和 XHR 的一些复杂交互可能会因此引发安全漏洞。
所以不推荐在浏览器内部的脚本环境中使用jquery。
从框架脚本进行 DOM 操作的两个选项是
a) 直接从框架脚本中使用标准 DOM API。插件脚本在启用 ES6 支持的情况下自动运行(例如解构、箭头函数等),并且不必担心跨浏览器兼容性。换句话说:不需要jquery
b) 如果使用 jquery 是绝对必要的,例如因为一些第三方库依赖于它,所以可以创建一个sandbox,以当前窗口为原型,并使用subscript loader向其中注入jquery和自定义脚本。
创建沙盒以将其与不受信任的内容隔离并同时放弃系统权限的推荐方法:
let options = {
// this is the name reported in about:memory
sandboxName: "<addon name> <purpose of sandbox>",
// ensure that jquery sees the window as global
sandboxPrototype: content,
// reduces GC overhead by having the sandbox reside in the same space as target window
sameZoneAs: content,
// don't include components object that grants access to privileged APIs
wantComponents: false,
// helper functions for interacting with untrusted content
wantExportHelpers: true,
// clean view of DOM APIs, otherwise untrusted content could override prototypes
wantXrays: true,
// addon ID, used by addon debugger and memory reporting
// sdk addons can obtain it via require("sdk/self").id, other addons define it in the install.rdf
metadata: {addonID: id}
}
// set the security principal to an extended principal covering the target window
let sandbox = Cu.Sandbox([content], options)
// structured-clone objects into the sandbox
sandbox.myData = {foo: "bar"}
loader.loadSubscript("resource://myaddon-id/libs/jquery.js", sandbox, "UTF-8")
loader.loadSubscript("resource://myaddon-id/src/mypagescript.js", sandbox, "UTF-8")
// call custom function created by mypagescript.js
sandbox.myFunc()
请注意,沙盒仅在页面的生命周期内有效,因此如果框架被导航到新窗口(@987654328@ 对象),您将必须创建一个新沙盒
以上基本就是SDK的page-mod和webextensionscontent-scripts使用的底层底层API。