有一些与此相关的问题,但使用unsafeWindow
的一般"解决方案"不适合我。
我正在尝试使用Stack Exchange Javascript SDK。
如此:
// ==UserScript==
// @name testing
// @include http://stackoverflow.com/*
// @require https://api.stackexchange.com/js/2.0/all.js
// @version 1
// @grant none
// ==/UserScript==
console.log(SE);
SE.init({
clientId: 1234,
key: 'my key',
channelUrl: location.protocol + '//stackoverflow.com/blank',
complete: function (d) {
console.log(d);
console.log('SE init');
}
});
这并不:
// ==UserScript==
// @name testing
// @include http://stackoverflow.com/*
// @require https://api.stackexchange.com/js/2.0/all.js
// @version 1
// @grant GM_setValue
// ==/UserScript==
console.log(SE);
SE.init({
clientId: 1234,
key: 'my key',
channelUrl: location.protocol + '//stackoverflow.com/blank',
complete: function (d) {
console.log(d);
console.log('SE init');
}
});
然而,两个版本都为console.log(SE)
记录Object { authenticate: n(), init: r() }
,我无法理解,因为这意味着脚本可以访问SE对象。
"不工作",我的意思是它什么也不做;在第一个console.log(SE)
之后没有任何内容被记录到控制台。
我不知道如何让这个库工作。有人有什么想法吗?这与设置授予值时在Firefox上启用的沙箱有关。
这确实,顺便说一句,在Chrome上的工作方式,但我的理解是,这两个沙箱是相当不同的。有没有办法绕过这个阻止SE.init()
功能运行的Firefox沙盒?我试过unsafeWindow.SE...
,但这不起作用——我不认为它应该有所不同,因为脚本总是可以访问SE对象;它只是很难调用它!
一个快速hack将注入你的整个代码,包括简单的api脚本,到网页和使用消息传递(dispatchEvent + addeventlistener 'message'事件在窗口对象)访问GM_
函数不可用于注入的脚本。
它不像GM沙箱那样安全:如果您安装了专门针对窃取密钥的扩展或用户脚本,则可以通过DOM突变观察者/侦听器或onbeforescriptexecute
事件侦听器截获API密钥。
// ==UserScript==
// @name testing
// @include http://stackoverflow.com/*
// @include https://stackoverflow.com/*
// @resource SE_JS_API https://api.stackexchange.com/js/2.0/all.js
// @version 1
// @grant GM_setValue
// @grant GM_getResourceText
// ==/UserScript==
document.head.appendChild(document.createElement('script')).text =
GM_getResourceText('SE_JS_API') + ';(' + function() {
SE.init({
clientId: 1234,
key: 'my key',
channelUrl: location.protocol + '//stackoverflow.com/blank',
complete: function (d) {
console.log(d);
console.log('SE init');
}
});
} + ')(); this.remove();'
API脚本被声明为资源,因此它只在脚本安装时下载一次,并与脚本一起存储在用户的硬盘上。
或者,注入API并通过unsafeWindow
和exportFunction
为回调调用它:
document.head.appendChild(document.createElement('script')).text =
GM_getResourceText('SE_JS_API');
unsafeWindow.SE.init({
clientId: 1234,
key: 'my key',
channelUrl: location.protocol + '//stackoverflow.com/blank',
complete: exportFunction(function (d) {
console.log(d);
console.log('SE init');
}, unsafeWindow),
});
一个合适的解决方案是通过GM_xmlhttpRequest手动访问实际的API,直到有人发布更好的库。在Tampermonkey中,你还需要为API url添加权限:// @connect api.stackexchange.com
.