【问题标题】: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:stackoverflow.com/questions/23752156/… - 请注意此建议
  • @Juhana 我不熟悉 JSP 的 JSON 字符串化器,所以我认为一般警告是合理的。如果可以信任\u-encode麻烦的字符,那就没有问题了。
  • @AaronDufour 从问题中可以看出它对<> 之类的字符进行编码,可以肯定的是,它还可以对已知会破坏兼容性的字符进行编码。
  • @Juhana 变量名jsonArr 表明 OP 已经完成了字符串化,我不愿意假设所述字符串化意识到 JSON 与 JavaScript 在 Unicode 方面的复杂性。我现在明白这只是一个误导性的名称。

标签: javascript jquery json jsp interpolation


【解决方案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:不,只有双引号是问题所在。不管你在字符串文字中使用什么引号,因为它已经是一个转义序列,所以它不会破坏主字符串。
    【解决方案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"。这是唯一需要逃避的人。
    猜你喜欢
    • 2015-03-20
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-04
    相关资源
    最近更新 更多