【问题标题】:Alternatives for Javascript eval [duplicate]Javascript eval 的替代方案 [重复]
【发布时间】:2011-08-19 21:31:54
【问题描述】:

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

我的问题有两个:

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

【问题讨论】:

  • 请发布一个示例,您不确定是否可以替换它。否则很难帮你。
  • 好吧,问题是,我想不出一个我无法替换的例子。但是,我也想不出一个通用的替换 eval 的方法(每种情况都不同)。
  • @Tony:你有真实的用例吗,或者你只是想看看是否存在从eval 到其他语言结构的通用转换?
  • Mozilla 允许 eval 工作。截至 2018 年 8 月。

标签: javascript firefox eval security


【解决方案1】:

可替代的最常见用途如下。我当然会先使用这些。

  1. 访问动态属性

    请使用:obj[keyAsVariable]

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

  2. 解析 JSON

    请使用JSON.parse(data)

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

  3. 计算用户输入

    一定要用library

    不要使用eval(input)

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

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

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

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

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

【讨论】:

  • 谢谢,请求脚本方法正是我要找的。​​span>
  • @pimvdb 无需将其退回到服务器。检查我添加的答案以获得该建议的替代方案...
【解决方案2】:

使用 Blob 作为脚本加载

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

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。

【讨论】:

  • 不重复
  • 超级!如果code必须接收参数并且有返回值,需要修改什么?
【解决方案3】:

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

【讨论】:

  • 抱歉,您能再解释一下吗?如果我想运行: eval(document.cookie= 'some user input');如何在不使用 eval 的情况下将其替换为 javascript 函数调用?
  • 因此,如果您尝试执行的代码是var test = "hello world";,您可以将其转换为function go() { var test = "hello world" },然后您将动态生成一个脚本标签来加载该代码并评估
  • 我也想过这个,但是这对所有情况都有效吗?
猜你喜欢
  • 2013-04-08
  • 1970-01-01
  • 2013-05-22
  • 2010-10-31
  • 2012-01-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-20
  • 2018-11-14
相关资源
最近更新 更多