" eval不是一个功能"使用iframe和Greasemonkey / Scriptish时

时间:2012-09-26 19:02:17

标签: iframe greasemonkey scriptish

有什么方法可以让这段代码在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。

请对此有所了解。

1 个答案:

答案 0 :(得分:1)

有几件事:

  1. 代码有错误; getElementsById不是函数。
  2. 如果@grant none指令适用,那么Greasemonkey 1.0或更高版本中的 可以正常工作 。更多内容如下。
  3. 对于Scriptish,所有其他浏览器以及@grant none不可能的Greasemonkey场景;您必须 “注入” 代码。更多内容如下。
  4. 正如Jeremy J Starcher所说,eval()应该尽可能避免。 eval()使性能,维护,调试和安全性变得更加困难。

  5. 对于Greasemonkey 1.0及更高版本:

    某些方案中,Greasemonkey不再使用XPCNativeWrapper。见the doc for the @grant directive

    所以这意味着(1)如果你的脚本不使用GM_函数,(2)脚本指定@grant none,那么你的代码将按原样运行(getElementsById除外)错字)。

    请注意,没有其他脚本引擎可以做到这一点。 (原因很简单.Greasemonkey关于@grant和沙箱的新行为充其量是有争议的。)

    如果您希望使用GM_函数,则必须注入iframe代码。请参阅下一节。


    For Scriptish,Privileged Greasemonkey,Chrome等:

    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);
    }