Javascript Firefox 22中的NS\u错误\u XPC\u错误\u操作\u关于\u WN\u协议异常
我维护的插件似乎与Firefox22有问题。有一个使用loadFrameScript的JavaScript模块,它反过来使用mozIJSSubScriptLoader注入一些库。loadFrameScript引入的文件类似于以下内容:Javascript Firefox 22中的NS\u错误\u XPC\u错误\u操作\u关于\u WN\u协议异常,javascript,firefox-addon,Javascript,Firefox Addon,我维护的插件似乎与Firefox22有问题。有一个使用loadFrameScript的JavaScript模块,它反过来使用mozIJSSubScriptLoader注入一些库。loadFrameScript引入的文件类似于以下内容: // Create a JS sub-script loader. var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Compo
// Create a JS sub-script loader.
var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
// Create a context object.
var executionContext = Object.create(content);
// Load the libraries.
loader.loadSubScript("chrome://my-package/content/libs/jquery.js", executionContext);
loader.loadSubScript("chrome://my-package/content/logic.js", executionContext);
但是,加载jQuery的行为会引发异常:
错误:NS\u错误\u XPC\u错误\u对\u WN\u PROTO的操作:对WrappedNative prototype对象的非法操作
源文件:chrome://my-package/content/libs/jquery.js
电话:829
jQuery在这一行似乎没有做任何疯狂的事情,只是调用setTimeout。在谷歌上搜索这条消息,我在分机上发现了类似的情况,但没有解决。我不知道我应该做些什么,或者是什么改变打破了我在Firefox22中加载jQuery的方式。有没有更好的方法引入jQuery
更新
这确实是最严重的问题。我放弃了使用executionContext
对象,因为我甚至不记得当初为什么要使用它,而jQuery会加载到内容中
loader.loadSubScript("chrome://my-package/content/libs/jquery.js", content);
loader.loadSubScript("chrome://my-package/content/logic.js", content);
但是,现在,也被加载到内容中的其他脚本不能使用sendAsyncMessage
。我认为这是有意义的,因为它是一个全新的范围,没有插件API,但现在我不知道如何读取页面DOM。如何将我的逻辑和jQuery加载到内容中
,并且仍然保持发送异步消息
结果的能力?只要我的两分钱-
我还维护了一个遇到问题的扩展。对我来说,解决方案实际上与scriptish中指出的相同-使用window.xxxx,而不是直接引用该方法
例如,前面的一行直接调用setTimeout(),在我将其更改为window.setTimeout()后,代码可以正常工作
既然你说这条线除了调用setTimeout之外什么也不做,我想这是同一个问题。尝试添加窗口。在那个电话之前
祝你好运 您首先使用executionContext
的可能原因是,否则内容将直接定义在内容上,这可能与网站、其他加载项冲突和/或泄漏到网站。所以最好在装东西的窗口周围放一个包装器
我刚刚编写了一个基于框架脚本的最小“内容脚本”加载程序。没什么大不了的,但应该完成这项工作。我在FX24上验证了jquery将在其中工作,并且内容不会泄漏到内容窗口中
// Frame scripts share a scope, so better not mess them up ;)
(function() {
"use strict";
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const utils = {};
try {
throw new Error();
}
catch (ex) {
let url = ex.fileName.replace(/\/[^\/]*?$/, "/");
const ssm = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
Object.defineProperties(utils, {
"url": {
enumerable: true,
value: function(fn) {
return url + fn;
}
},
"mayLoad": {
enumerable: true,
value: function(o) {
let node = (o.document || o);
let window = (o.ownerDocument || o).defaultView || o;
try {
return window.location != "about:blank" &&
!ssm.isSystemPrincipal(node.nodePrincipal);
}
catch (ex) {
Cu.reportError(ex);
return false;
}
}
},
});
Object.freeze(utils);
}
try {
const loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader);
// Create a context object for each window that get's loaded.
// Or use DOMWindowCreated, like the add-on manager does to install
// the InstallTrigger.
addEventListener("DOMContentLoaded", function(e) {
let window = e.target.defaultView;
if (!utils.mayLoad(window)) {
// Refuse to load in chrome (system) pages.
return;
}
// Need to create our context in the window scope (compartment).
// The reason to create a wrapper/context it in the first place
// is to avoid clashes with other add-ons, the website itself,
// etc.
let executionContext = Cu.createObjectIn(window);
// Wire up the window to be the prototype.
executionContext.__proto__ = window;
// Add some useful stuff you want the "content scripts" to have
// access to.
Object.defineProperties(executionContext, {
"sendAsyncMessage": {
enumerable: true,
value: sendAsyncMessage.bind(null)
},
"reportError": {
enumerable: true,
value: Cu.reportError.bind(Cu)
},
"doSomething": {
enumerable: true,
value: function(arg) {
Cu.reportError("did something " + arg);
}
},
"loadScript": {
enumerable: true,
value: function(fn) {
loader.loadSubScript(utils.url(fn), executionContext);
}
}
});
// Normalize the properties, i.e. move them over to the correct
// window scope (compartment);
Cu.makeObjectPropsNormal(executionContext);
// Load initial scripts
executionContext.loadScript("test.js");
});
}
catch (ex) {
content.console.error(ex);
}
})();
重点是:
- 使用
Cu.createObjectIn(窗口)
正确设置作用域(Spidermonkey中的隔间),并避免出现NS\u错误\u XPC\u错误\u OP\u关于\u WN\u PROTO的异常
- 如果您在上下文中定义了其他内容,请使用
Cu.makeObjectPropsNormal()
- 不要尝试将内容注入chrome特权窗口(
utils.mayLoad
)
throw new Error()