Javascript eval 的替代方案

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7127652/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 23:02:56  来源:igfitidea点击:

Alternatives for Javascript eval

javascriptfirefoxevalsecurity

提问by Tony Stark

Mozilla's Content Security Policydisallows the use of javascript eval function as well as inline scripts. They claim that all instances of eval can be replaced by another (hopefully safer) function. I agree in most scenarios, Javascript eval can be replaced, but I'm not sure whether the replacement is possible for every case.

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

My question is twofold:

我的问题是双重的:

  1. Is there a generic way to replace every javascript eval function? (doesn't have to be safe)
  2. Is there a case where the Javascript eval cannot be replaced?
  1. 有没有通用的方法来替换每个 javascript eval 函数?(不一定要安全)
  2. 是否存在无法替换 Javascript eval 的情况?

回答by pimvdb

The most common uses which can be substituted are the following ones. I would certainly use these first.

可以替代的最常见用途如下。我肯定会首先使用这些。

  1. Accessing dynamic properties

    Do use: obj[keyAsVariable]

    Don't use eval('obj.' + keyAsVariable)

  2. Parsing JSON

    Do use JSON.parse(data)

    Don't use eval('(' + data + ')')

  3. Calculating user input

    Do use a certain library

    Don't use eval(input)

  1. 访问动态属性

    使用: obj[keyAsVariable]

    不要使用 eval('obj.' + keyAsVariable)

  2. 解析 JSON

    使用 JSON.parse(data)

    不要使用 eval('(' + data + ')')

  3. 计算用户输入

    使用某个

    不要使用 eval(input)

If really necessary, you can also send the script to a server which simply echoes it back, and you can request it as a script tag. It won't use evalbut still execute it. It isn't safe as it's sent twice over the Internet.

如果真的有必要,您还可以将脚本发送到服务器,服务器会简单地将其回显,然后您可以将其作为脚本标签进行请求。它不会使用eval但仍会执行它。它不安全,因为它通过 Internet 发送了两次。

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

request_scriptcould be a file implemented in PHP, like the following. Again, it's bad practice but is a generic way of circumventing eval.

request_script可以是用 PHP 实现的文件,如下所示。同样,这是不好的做法,但它是规避eval.

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

You could say that this also automatically answers your second question with 'no'.

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

回答by secretformula

You could wrap the java script within a function call similar to JSONP and then dynamically create a script tag to load that.

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

回答by Wilt

Load as script using a Blob

使用 Blob 作为脚本加载

Instead of using evalyou can also use a Bloband load the code as if it was an external jsfile: To ensure that functions or variables that are inside the code that you are loading are available you need to use a callbackmethod that will be triggered onloadevent.

除了使用,eval您还可以使用 aBlob并像加载外部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);

NoteBe aware that the danger for code injection is similar to eval.

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