Javascript eval的替代品

时间:2011-08-19 21:31:55

标签: javascript firefox eval security

Mozilla的Content Security Policy不允许使用javascript eval函数以及内联脚本。他们声称所有eval实例都可以被另一个(希望更安全)功能所取代。我同意在大多数情况下,Javascript eval可以被替换,但我不确定是否可以替换每种情况。

我的问题有两个:

  1. 是否有替换每个javascript eval函数的通用方法? (不必是安全的)
  2. 是否存在无法替换Javascript eval的情况?

3 个答案:

答案 0 :(得分:13)

可以替代的最常见用途是以下几种。我当然会先使用这些。

  1. 访问动态属性

    请使用:obj[keyAsVariable]

    请勿使用eval('obj.' + keyAsVariable)

  2. 解析JSON

    请使用JSON.parse(data)

    请勿使用eval('(' + data + ')')

  3. 计算用户输入

    请使用某个library

    请勿使用eval(input)

  4. 如果确实有必要,您还可以将脚本发送到服务器,该服务器只需将其回送,您可以将其作为脚本标记请求。它不会使用eval但仍会执行它。它不安全,因为它通过互联网发送两次。

    var s = document.createElement('script')
    s.src = 'request_script?data=' + data;
    document.getElementsByTagName('head')[0].appendChild(s);
    

    request_script可以是用PHP实现的文件,如下所示。同样,这是一种不好的做法,但却是绕过eval的通用方法。

    <?
    echo $_GET['data'];
    ?>
    

    您可以说这也会自动以“否”回答您的第二个问题。

答案 1 :(得分:2)

您可以在类似于JSONP的函数调用中包装java脚本,然后动态创建脚本标记以加载它。

答案 2 :(得分:2)

使用Blob

加载为脚本

您可以使用eval而不是使用Blob,并加载代码,就像它是外部js文件一样: 要确保您正在加载的代码中的函数或变量可用,您需要使用将被触发callback事件的onload方法。

var code = "console.log('hello world');";

// With eval:
eval(code);

// With a blob:
var blob = new Blob([code], {type: 'text/javascript'});
var urlCreator = window.URL || window.webkitURL;
var url = urlCreator.createObjectURL( blob );

function loadScript(url, callback)
{
    // Add a the script tag to the head
    var head = document.getElementsByTagName('head')[0];
    var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;

    // Bind the callback (depends on browser compatibility).
    script.onreadystatechange = callback;
    script.onload = callback;

    // Load the script
    head.appendChild(script);
}

// Any variables or methods inside the code will be on callback.
loadScript(url, callback);

注意 请注意,代码注入的危险与eval类似。