为啥 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&lt;/div&gt;") 中引号的 unicode 转义序列,方法是使用

JSON.parse('["id":61693,"name":"Más","id":61690,"name":"\u0027\\u0022\u003C/div\u003E"]'
//                                                               ^

或转义引号字符 ("'\"&lt;/div&gt;"):

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 数组?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Python 的原始字符串文字不能以单个反斜杠结尾?

为啥我们不能递增 (++) 或递减 (--) 数字文字

为啥在写入字符串文字时 scanf 不能按预期工作? [复制]

为啥这种语法专门用于初始化字符串文字而不能用于字符数组? [复制]

为啥这个 Json 不能从 HTTP 请求中解析?

为啥不能从文件中解析 JSON?