有什么方法可以让这段代码在Greasemonkey / Scriptish中运行,或者我是否必须将它注入网页本身?
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementsById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
使用source时,此代码可以正常工作:
<script type="text/javascript" src="test.js"></script>
但是当在Greasemonkey脚本中使用时,我发现存在某种安全障碍,我不太熟悉并尝试使用unsafeWindow来绕过XPCNativeWrapper。
请对此有所了解。
答案 0 :(得分:1)
有几件事:
getElementsById
不是函数。@grant none
指令适用,那么Greasemonkey 1.0或更高版本中的 可以正常工作 。更多内容如下。@grant none
不可能的Greasemonkey场景;您必须 “注入” 代码。更多内容如下。eval()
应该尽可能避免。 eval()
使性能,维护,调试和安全性变得更加困难。
在某些方案中,Greasemonkey不再使用XPCNativeWrapper
。见the doc for the @grant
directive。
所以这意味着(1)如果你的脚本不使用GM_
函数,(2)脚本指定@grant none
,那么你的代码将按原样运行(getElementsById
除外)错字)。
请注意,没有其他脚本引擎可以做到这一点。 (原因很简单.Greasemonkey关于@grant
和沙箱的新行为充其量是有争议的。)
如果您希望使用GM_
函数,则必须注入iframe代码。请参阅下一节。
Scriptish,Sandboxed Greasemonkey,Chrome等都不能在各自的沙箱中处理iframe。 (见these Q's, for example。)
从GM / userscript运行此类代码的唯一可靠方法是注入它。像这样:
function gmMain () {
body = document.getElementsByTagName("body")[0];
fakeConsole = 'window.top._console';
injected = document.getElementById("sandbox") ? true : false;
sandboxframe = injected ? document.getElementById("sandbox") : document.createElement('iframe');
sandbox = null;
if (!injected) {
body.appendChild(sandboxframe);
sandboxframe.setAttribute('id', 'sandbox');
sandboxframe.setAttribute('style', "display:none")
}
var p = sandboxframe.contentWindow.eval('1 + 1');
console.log(p);
}
addJS_Node (null, null, gmMain);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}