如何通过HTTP发送Unicode JSON?

时间:2016-01-15 09:37:33

标签: json http unicode encoding utf-8

RFC 4627第3节说

  

JSON文本应以Unicode编码。默认编码为UTF-8。

     

由于JSON文本的前两个字符始终为ASCII      字符[RFC0020],可以确定是否为八位字节      通过查看,流是UTF-8,UTF-16(BE或LE)或UTF-32(BE或LE)      在前四个八位字节中的空值模式。

       00 00 00 xx  UTF-32BE
       00 xx 00 xx  UTF-16BE
       xx 00 00 00  UTF-32LE
       xx 00 xx 00  UTF-16LE
       xx xx xx xx  UTF-8

我正在将U+20AC的UTF-8编码JSON字符串作为application / json提供。

$ curl -D - http://localhost:8000/test.json
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.6
Date: Fri, 15 Jan 2016 09:24:53 GMT
Content-type: application/json
Content-Length: 6
Last-Modified: Fri, 15 Jan 2016 09:23:13 GMT

"€"

$ curl -s http://localhost:8000/test.json | hexdump
0000000 e222 ac82 0a22                         
0000006

但Chrome Firefox似乎都在使用其他一些编码,因为两者都显示

"€"

如果将Content-Type更改为application/json; charset=utf-8,则会显示预期结果。

charsetapplication/json的补充内容,我不确定向其添加额外参数是否合法。

这一切都令人困惑。

某处有错误吗?我通过HTTP传输UTF-8编码的JSON文档的正确方法是什么?

2 个答案:

答案 0 :(得分:4)

您的回答是正确的。 charset不应对application/json执行任何操作,因为它是text/类型的参数; JSON处理器将忽略它。

问题是Chrome和Firefox在这里没有充当JSON处理器;他们没有解析或验证响应内容中的任何内容。他们正在回到他们常规的旧文本查看器,以便将内容显示为text/plain,前提是这样做比没有好。

不幸的是,纯文本查看器有关于猜测编码的规则,这些编码与JSON的仅内容信令规则不匹配。 IE将application/json视为未知二进制类型并提示您下载它的行为实际上是更正确的做法。

答案 1 :(得分:2)

您使用的content-type标题字段完全有效。

RFC 2616 that defines header fields in HTTP 1.1的一部分将分号后的编码视为一种有效的方法。

如果您没有指定字符集,浏览器将使用定义的默认值(ISO-8859-1,在您的情况下会发生这种情况)或根据其设置尝试自动 - 检测字符集。

正如Julian指出的那样(您可能已经知道)application/json内容类型不需要,也不需要添加charset

浏览器似乎错误地处理了application/json个响应并回退到ISO-8859-1,即使它们不应该。