javascript中的JSON字符编码与java不同

Posted

技术标签:

【中文标题】javascript中的JSON字符编码与java不同【英文标题】:JSON character encoding in javascript different from java 【发布时间】:2014-07-31 21:44:26 【问题描述】:

下面的java代码

    JSONObject obj = new JSONObject();
    try
        obj.put("alert","•é");
        byte[] test = obj.toString().getBytes("UTF-8");
        logger.info("bytes are"+ test);
     catch (JSONException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
     catch (UnsupportedEncodingException e) 
        // TODO Auto-generated catch block
        e.printStackTrace();
    ;

产生一个JSONObject,它转义子弹字符,但不是带有grave的拉丁字母e,例如“”\u2022é”,字节码是[123,34,97,108,101,114,116,34,58 , 34, 92, 117, 50, 48, 50, 50, -61, -87, 34, 125]

如何在 javascript 中获得完全相同的输出(就字节序列而言)?我不明白为什么 JSONObject 只转义一个字符而不转义另一个字符。我不知道它遵循什么规则。

似乎在 javascript 中我只能转义除 ASCII 以外的所有内容(例如。\u007f-\uffff)或根本不转义。

谢谢!

【问题讨论】:

创建byte[] 的目的是什么?这是转义显示的另一个问题。 因为后面会用到字节数组的长度,所以前端javascript代码需要在java代码中计算出最终字节数组的确切长度 后端应该计算长度。前端可以猜测长度,但负责和权威的来源是后端(应该理解,长度本身并不一定是规范的,而仅仅是当前操作的结果)。 不幸的是,UI 无法承受后端调用来执行此操作,它需要在输入字符时立即提供用户反馈。 【参考方案1】:

发生了两种不同的事情:Unicode 编码JSON 字符串转义

根据 JSON RFC 的 2.5 Strings:

.. 所有 Unicode 字符都可以放在 引号除了必须转义的字符..

任何字符都可以转义。如果角色在 Basic 多语言平面(U+0000 到 U+FFFF),那么它可能是 表示为一个六字符序列.. [和 BMP 之外的字符被转义为 UTF-16 编码的代理对]

"•é""\u2022é"的JSON字符串等价。转义(附加)字符完全取决于序列化实现,并且两种形式都有效。

正是这个 JSON 字符串(它是 Unicode 文本)在转换为字节流时可以被编码。在示例中,它通过 UTF-8 编码进行编码。然后,JSON 字符串可能是等价的


关于JSONObject的规则,escapes according to

    c < ' '
|| (c >= '\u0080' && c < '\u00a0')
|| (c >= '\u2000' && c < '\u2100')

[\u2000, \u2100] 范围内的这些字符可能被转义的一个原因是确保生成的 JSON 也是有效的 JavaScript。文章JSON: The JavaScript subset that isn't 讨论了这个问题:问题是Unicode 代码点\u2028\u2029 在JavaScript 字符串文字中被视为行终止符,而不是JSON。 (该范围内还有其他 Unicode Separator 字符:不妨一口气抓住它们。)

【讨论】:

我明白,但在这种情况下,javascript 需要确切知道 byteArray 的样子才能获得正确的长度(Java 代码稍后将使用相同的长度)。因此,“等效”是不够的。前端js代码需要和java代码完全一样的方式对json字符串进行转义。 这不是一个好主意(事实上,我想说这是一个糟糕的主意)。无论如何,我已经更新了答案以包含与 JSONObject 一起使用的规则。您必须编写一个自定义函数来执行类似的转义(在任何特定的JSON.stringify 实现中不保证遵循这种转义),然后创建一个函数来进行 UTF-8 编码或 UTF-8-encoded-length-猜测结果 - 字节计数的长度可以仅通过查看代码点大小来完成。您还需要处理 JSON 标记之间的空格。 @user3277841 为什么Javascript 需要知道byte[] Java 代码使用的长度? JSON 的重点难道不是要有一个漂亮、整洁的字符串格式来传递,而且不必担心像这样琐碎的细节吗? 因为用户在文本框中输入字符串时,UI需要检查字符串的长度,而字符串的长度由原帖中的java代码决定。 @user3277841 字符串的长度可能应该是用于 UI 目的的逻辑字符(而不是编码长度)。如果可能,考虑为后端添加“slack”(即更大的 varchar);也可以折叠 Java 中的“\u....” JSON(通过替换正则表达式)以减少扩展差异。

以上是关于javascript中的JSON字符编码与java不同的主要内容,如果未能解决你的问题,请参考以下文章

用 html 数据属性中的字符串编码 JSON

将 Javascript 对象编码为 Json 字符串

javascript数据相关处理,序列化反序列化,数据编码与解码

Play 框架中的 Json 响应字符编码

json字符串在javascript和java代码中的表示方式

Golang 处理 Json:编码