为啥 Javascript 不能从字符串文字中解析这个 JSON 数组?
Posted
技术标签:
【中文标题】为啥 Javascript 不能从字符串文字中解析这个 JSON 数组?【英文标题】:Why can't Javascript parse this JSON array from a string literal?为什么 Javascript 不能从字符串文字中解析这个 JSON 数组? 【发布时间】:2015-09-17 09:57:19 【问题描述】:我想做的很简单。将此包含 json 对象的数组解析为 javascript 数组。
var merchantsJson = JSON.parse('["id":61693,"name":"Más","id":61690,"name":"\u0027\u0022\u003C/div\u003E"]');
但 unicode 字符 \u003C 似乎破坏了解析器。在 chrome 控制台中,我看到“Uncaught SyntaxError: Unexpected token
更多信息。以上是代码被评估的内容。实际上代码中包含一个jsp表达式。
var merchantsJson = JSON.parse('$jsonArr');
如果我删除单引号,没有问题,但 eclipse 给我一个“缺少分号”的错误消息。是否可以像我试图做的那样用引号解析数组?
【问题讨论】:
您收到了很多与 Juhana 的评论类似的回复,但请注意 JSON 实际上并不是 JavaScript 的子集。在某些极端情况下,当您使用 Unicode 时,JavaScript 解释器无法正确解析有效的 JSON:***.com/questions/23752156/… - 请注意此建议 @Juhana 我不熟悉 JSP 的 JSON 字符串化器,所以我认为一般警告是合理的。如果可以信任\u
-encode麻烦的字符,那就没有问题了。
@AaronDufour 从问题中可以看出它对<
和>
之类的字符进行编码,可以肯定的是,它还可以对已知会破坏兼容性的字符进行编码。
@Juhana 变量名jsonArr
表明 OP 已经完成了字符串化,我不愿意假设所述字符串化意识到 JSON 与 JavaScript 在 Unicode 方面的复杂性。我现在明白这只是一个误导性的名称。
【参考方案1】:
您必须在 JSON 字符串中使用特殊字符,您可以使用 \ 字符对其进行转义。
您需要将\
替换为\\
。
[\"id\":61693,\"name\":\"Más\",\"id\":61690,\"name\":\"\\u0027\\u0022\\u003C/div\\u003E\"]
【讨论】:
【参考方案2】:因为你的字符串文字中有一个额外的"
,它是由\u0022
编码的:
> '["id":61693,"name":"Más","id":61690,"name":"\u0027\u0022\u003C/div\u003E"]'
["id":61693,"name":"Más","id":61690,"name":"'"</div>"]
简而言之,你在字符串中的 JSON 是无效的。您需要转义字符串文字 ("'\u0022</div>"
) 中引号的 unicode 转义序列,方法是使用
JSON.parse('["id":61693,"name":"Más","id":61690,"name":"\u0027\\u0022\u003C/div\u003E"]'
// ^
或转义引号字符 ("'\"</div>"
):
JSON.parse('["id":61693,"name":"Más","id":61690,"name":"\u0027\\\u0022\u003C/div\u003E"]');
// ^^
但是,实际上根本不需要使用 JSON。只需将 JS 数组字面量输出到您的代码中即可:
var merchantsJson = $jsonArr;
【讨论】:
只是想注意,在最后一个解析示例中额外的\
并不是真正需要的,因为 JSON 也会解释转义序列。无论哪种方式都可以,只是想我会提到它。
@squint:是的,这就像当时的第一个解决方案 :-) 我可能应该使用 \\\"
以获得额外的清晰度。
是的,除了它不必要地转义单引号,这对 JSON 没有特殊含义,因此解析器可以将它们作为实际引号字符而不是转义序列接收。同样,只是为人们注意它,因为这种转义的东西可能会令人困惑。一切都很好,而且一切正常。 :-)【参考方案3】:
这不是因为 \u003C,而是 \u0022 字符导致了问题,因为它是一个引号,JavaScript 将它视为字面上结束字符串。
您需要转义该字符:\\u0022
。
【讨论】:
\u0027
不是问题; \u0022
是。
是的,这两者都可能是问题,这取决于你如何开始你的字符串。
@AlejandroC:不,只有双引号是问题所在。不管你在字符串文字中使用什么引号,因为它已经是一个转义序列,所以它不会破坏主字符串。
谢谢@squint ***.com/questions/19176024/…【参考方案4】:
$jsonArr
的插值已经是一个 JavaScript 对象。当您将其包装在 '$jsonArr'
中时,这会将其转换为字符串,您必须使用 JSON.parse
。
没有必要把它变成一个字符串。你可以做var merchantsArray = $jsonArr
。 JSON 结构已经可以与 JavaScript 代码互操作。
【讨论】:
Eclipse 会抱怨它不是合法的 JavaScript,但这是意料之中的,因为它不是 JavaScript。这是一个可以生成 JavaScript 的模板。 这是正确答案。其他人都在治疗症状,而不是原因。 @Juhana,如果 JSON 是可信的并且它实际上是合法的 JS (which not all JSON is),这是一个正确的答案。如果它不受信任,正确的答案是将 JSON 正确转换为 JS 字符串文字,这是其他答案所建议(或试图)的。正如你所说,它们并没有治疗症状。 @ikegami 是的,你误解了它。它说虽然这些字符是非法的作为符号,但它们在编码时是合法的(即"foo\u2028bar"
作为 JSON 和 JS 字符串都是合法的。)
JSON 不受信任,这就是它被引用的原因。【参考方案5】:
尝试将\u
替换为\\u
。如果不这样做,JSON 解析器会接收已解码的 Unicode,这会创建污染的 JSON。
【讨论】:
JSON 中的 decoded Unicode 有问题...事实上它需要 Unicode。唯一真正的问题是一个字符代表一个双引号,它关闭了解析器正在解释的 "sub-string"。这是唯一需要逃避的人。以上是关于为啥 Javascript 不能从字符串文字中解析这个 JSON 数组?的主要内容,如果未能解决你的问题,请参考以下文章
为啥在写入字符串文字时 scanf 不能按预期工作? [复制]