【问题标题】:Does eval() first makes a literal translation of the evaluated string?eval() 是否首先对评估的字符串进行字面翻译?
【发布时间】:2013-06-30 08:42:20
【问题描述】:

尝试在浏览器中执行以下代码:

eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS COOL') + "')); })()");

它应该打印出THIS IS COOL, 但是,如果你执行这个:

eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS "NOT" COOL') + "')); })()");

它将失败,而不是打印THIS IS "NOT" COOL

谁能解释为什么会这样?


注意这一点:

JSON.stringify('THIS IS "NOT" COOL') 的结果是字符串"THIS IS \"NOT\" COOL"

如果你尝试执行JSON.parse("THIS IS \"NOT\" COOL"),它会失败,这是因为JS解析器会将字符串"THIS IS \"NOT\" COOL"解释为"THIS IS "NOT" COOL"

如果你执行JSON.parse(JSON.stringify('THIS IS "NOT" COOL')),它会起作用,因为字符串"THIS IS \"NOT\" COOL"是直接传递给JSON.parse的。

为什么它在这种情况下有效,但在前一种情况下无效?

我唯一的结论是 eval 在执行代码之前明确地对传递给它的所有内容进行转义,但我想确定并理解为什么 eval 设计为这样工作。

【问题讨论】:

  • 你的第二个代码在没有 eval 的情况下做同样的事情...
  • eval() 在带注释的 ES5...
  • @dandavis 我明白了,eval 的问题是我需要它在字符串上下文中评估 JSON.stringify 返回的字符串。
  • @Teemu 很好,谢谢,所以'为了安全',你认为像eval(code.replace(/\/g, '\\\\')); 这样的事情就足够了吗?
  • @almosnow 我怀疑eval 永远不会是任何问题的安全解决方案......

标签: javascript json eval quotes


【解决方案1】:

这里的问题是字符转义。查看字符串拼接的结果:

"(function() { console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); })()"

请注意,这是实际输出,这 不是 字符串文字。 \ 在这里是文字字符,不是转义字符(我只包括了外引号以表示我在谈论一个字符串)。

使用eval,字符串被评估为以下代码:

(function() { 
    console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); 
})()

此时,\"实际上被解释为字符转义序列,即字符串literal'"THIS IS \"NOT\" COOL"'为:

"THIS IS "NOT" COOL"

这是一个无效的 JSON 编码字符串。

因此你得到错误

SyntaxError: Unexpected token N


eval 不会对您传递的字符串做任何事情,它会以获取它的方式进行解释。

【讨论】:

  • 感谢您的宝贵时间,我认为 eval 确实做了一些事情,因为 eval("(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS "NOT" COOL') + "')); })()"); 不起作用。
  • 有什么区别?如果我将您评论中的代码与您问题中的第二个示例进行比较,则它是相同的。可能我的介绍不清楚。开头的字符串值是运行"(function() { console.log(JSON.parse('" + JSON.stringify('THIS IS "NOT" COOL') + "')); })()"的*结果。
  • JSON.stringify 返回 "THIS IS \"NOT\" COOL" 而不是 "THIS IS "NOT" COOL"。它不应该被转义,因为解析器没有被调用,我没有明确地写字符串"THIS IS \"NOT\" COOL"
  • 是的,JSON.stringify 返回该字符串。然后你将它与另一个字符串连接起来。并将连接的结果传递给eval
  • 我认为 eval 需要在执行代码之前进行“额外的”循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多