我用a solution proposed here。
它是通过创建一个特殊的协议来实现的,该协议由您的 Firefox 插件处理,然后从其文件夹中请求资源。
请注意,如果资源文件夹可能包含非公开内容,那么我会添加额外的检查,以仅允许这些真正打算通过 Web 访问的资源。
上面提到的帖子所附的自定义协议代码是available here:
/*
Makes any file within the data directory available to use in an iframe.
Replace this: require("sdk/self").data.url(...)
With this: require("name-of-this-file").url(...)
*/
var { Class } = require('sdk/core/heritage');
var { Unknown, Factory } = require('sdk/platform/xpcom');
var { Cc, Ci, Cr } = require('chrome');
var self = require("sdk/self");
var resourceProtocolHandler = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.getProtocolHandler('resource');
var scheme = "res-" + self.id.toLowerCase().replace(/[^a-z0-9+\-\.]/g, "-");
var AddonProtocolHandler = Class({
extends: Unknown,
interfaces: ['nsIProtocolHandler'],
scheme: scheme,
defaultPort: -1,
protocolFlags: Ci.nsIProtocolHandler.URI_STD
| Ci.nsIProtocolHandler.URI_LOADABLE_BY_ANYONE
| Ci.nsIProtocolHandler.URI_SAFE_TO_LOAD_IN_SECURE_CONTEXT,
newURI: function(spec, originCharset, baseURI) {
let uri = Cc["@mozilla.org/network/standard-url;1"].createInstance(Ci.nsIStandardURL);
uri.init(uri.URLTYPE_STANDARD, this.defaultPort, spec, originCharset, baseURI);
return uri.QueryInterface(Ci.nsIURI);
},
newChannel: function(uri) {
if (uri.spec.indexOf(exports.url("")) != 0) {
throw Cr.NS_ERROR_ILLEGAL_VALUE;
}
var resourceUri = resourceProtocolHandler.newURI(uri.spec.replace(scheme + "://", "resource://"), uri.originCharset, null);
var channel = resourceProtocolHandler.newChannel(resourceUri);
channel.originalURI = uri;
return channel;
},
allowPort: (port, scheme) => false
});
Factory({
contract: "@mozilla.org/network/protocol;1?name=" + scheme,
Component: AddonProtocolHandler
});
exports.url = function(url) {
return self.data.url(url).replace("resource://", scheme + "://");
};
附加说明:对于page 脚本(不是content 脚本),此自定义协议有助于加载iframe 和其他HTML 元素,但不能加载XMLHttpRequest 或@ 987654328@。对于后者,仍然适用跨域限制并引发安全错误:“访问受限 URI 被拒绝”XMLHttpRequest 和“操作不安全”。为Worker。
相比之下,在 Chrome 下,XMLHttpRequest 到 web_accessible_resources 是允许的。 Worker 在 Chrome 下也没有实现对 web_accessible_resources 的访问。
但是对于Workers,您可以将此自定义协议网址用于importScripts 方法。使用它,您还可以解决将自定义资源加载到Workers 的问题。此代码也适用于 Chrome,作为使用 XMLHttpRequest 的替代方法。
var code = "self.onmessage = function (message)\
{\
self.onmessage = null;\
self.importScripts(message.data);\
};";
var blob = new Blob([code], {type: 'application/javascript'});
var blobUrl = URL.createObjectURL(blob);
var w = new Worker(blobUrl);
w.postMessage(*webAccessibleResourceUrl*);
URL.revokeObjectURL(blobUrl);