我正在编写一个使用json来表示其资源的web服务,我有点想到编写json的最佳方法。读json rfc(http://www.ietf.org/rfc/rfc4627.txt)很明显,首选编码是utf-8。但rfc还描述了一种用于指定字符的字符串转义机制。我假设这通常用于转义非ascii字符,从而使得结果utf-8有效ascii。
因此,假设我有一个json字符串,其中包含非ascii的unicode字符(代码点)。我的webservice应该只是utf-8编码并返回它,还是应该逃脱所有那些非ascii字符并返回纯ascii?
我希望浏览器能够使用jsonp或eval执行结果。这会影响决定吗?我对各种浏览器对utf-8的javascript支持的了解很少。
编辑:我想澄清一下,我对如何对结果进行编码的主要关注点是关于浏览器处理结果的问题。我读过的内容表明,特别是在使用JSONP时,浏览器可能对编码很敏感。我没有找到关于这个主题的任何非常好的信息,所以我将不得不开始做一些测试,看看会发生什么。理想情况下,我只想逃避所需的几个字符,只需要utf-8对结果进行编码。
答案 0 :(得分:74)
JSON规范需要解码器支持 UTF-8。因此,所有JSON解码器都可以处理UTF-8,就像它们可以处理数字转义序列一样。对于Javascript解释器也是如此,这意味着JSONP也将处理UTF-8编码的JSON。
JSON编码器使用数字转义序列的能力只是为您提供了更多选择。您可以选择数字转义序列的一个原因是,在您的编码器和预期解码器之间的传输机制不是二进制安全的。
您可能希望使用数字转义序列的另一个原因是阻止流中出现某些字符,例如<
,&
和"
,这些字符可能会被解释为HTML序列如果放置JSON代码而不转义为HTML或浏览器错误地将其解释为HTML。这可以防止HTML注入或跨站点脚本(注意:一些字符必须以JSON格式转义,包括"
和\
)。
一些框架,包括PHP的JSON实现,总是在编码器端为ASCII以外的任何字符执行数字转义序列。这旨在最大限度地兼容有限的传输机制等。但是,这不应被解释为JSON解码器出现UTF-8问题的迹象。
所以,我想你可以决定使用这样的:
只要使用UTF-8,除非您在编码器和解码器之间存储或传输的方法不是二进制安全的。
否则,请使用数字转义序列。
答案 1 :(得分:15)
然后使用PHP json_decode(),如果找到“é”就会失败,所以对于Firefox,Opera,Safari和Chrome,我要在json_decode()之前调用utf8_encode()。
注意:在我的测试中,IE和Firefox正在使用他们的原生JSON对象,其他浏览器正在使用json2.js。
答案 2 :(得分:12)
ASCII不在其中。使用UTF-8编码意味着您不使用ASCII编码。你应该使用转义机制的是RFC所说的:
可以放置所有Unicode字符 在引号内除外 对于必须的人物 逃脱:引号,反转 固体和控制字符 (U + 0000至U + 001F)
答案 3 :(得分:7)
我遇到了同样的问题。这个对我有用。请检查一下。
json_encode($array,JSON_UNESCAPED_UNICODE);
答案 4 :(得分:1)
通过读取json rfc(http://www.ietf.org/rfc/rfc4627.txt)可以清楚地看到,首选编码是utf-8。
仅供参考,RFC 4627不再是官方JSON规范。它在2014年被RFC 7159淘汰,然后在2017年被RFC 8259(当前规范)淘汰。
RFC 8259规定:
8.1。字符编码
在不属于封闭生态系统的系统之间交换的JSON文本必须使用UTF-8 [RFC3629] 进行编码。
传输JSON文本时,先前的JSON规范不需要使用UTF-8。但是,在唯一的实现互操作性的编码方面,绝大多数基于JSON的软件实现已选择使用UTF-8编码。
实现不得在网络传输的JSON文本的开头添加字节顺序标记(U + FEFF)。为了互操作性,解析JSON文本的实现可以忽略字节顺序标记的存在,而不是将其视为错误。
答案 5 :(得分:0)
我遇到了与é字符类似的问题...我认为评论“你可能提供的文字可能不是UTF-8”可能接近这里。我有一种感觉我的实例中的默认排序规则是别的,直到我意识到并更改为utf8 ...问题是数据已经存在,所以不确定它是否转换数据或者当我更改它时,在mysql中显示正常工作台。最终结果是php不会对json进行数据编码,只返回false。无论您使用什么浏览器作为导致我的问题的服务器,如果存在此char,php将不会将数据解析为utf8。就像我说不确定是否是由于在数据存在后将模式转换为utf8或仅仅是一个php错误。在这种情况下,请使用UDP/TLS/RTP/SAVPF