尝试在浏览器中执行以下代码:
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被设计为像这样工作。
答案 0 :(得分:2)
这里的问题是角色逃避。查看字符串连接的结果:
"(function() { console.log(JSON.parse('"THIS IS \"NOT\" COOL"')); })()"
请注意,这是实际输出,不是字符串文字。 \
这里是一个文字字符,而不是转义字符(我只包括外部引号来表示我正在谈论一个字符串)。
使用eval
,字符串将被评估为此代码:
(function() {
console.log(JSON.parse('"THIS IS \"NOT\" COOL"'));
})()
此时,\"
实际上被解释为字符转义序列,即字符串 literal '"THIS IS \"NOT\" COOL"'
的值为:< / p>
"THIS IS "NOT" COOL"
这是一个无效的JSON编码字符串。
因此你得到错误
SyntaxError: Unexpected token N
eval
对你传递的字符串没有任何作用,它被解释为它获取它的方式。