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
,则会显示预期结果。
但charset
是application/json
的补充内容,我不确定向其添加额外参数是否合法。
这一切都令人困惑。
某处有错误吗?我通过HTTP传输UTF-8编码的JSON文档的正确方法是什么?
答案 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,即使它们不应该。