it-swarm.dev

Codificação de caracteres JSON - o UTF-8 é bem suportado por navegadores ou devo usar seqüências de escape numéricas?

Eu estou escrevendo um webservice que usa json para representar seus recursos, e estou um pouco preso pensando na melhor maneira de codificar o json. Lendo o json rfc ( http://www.ietf.org/rfc/rfc4627.txt ) está claro que a codificação preferida é utf-8. Mas o rfc também descreve um mecanismo de escape de string para especificar caracteres. Eu suponho que isso geralmente seria usado para escapar de caracteres não ascii, tornando assim o asci utf-8 válido.

Então, digamos que eu tenha uma string json que contenha caracteres unicode (code-points) que não sejam ascii. O meu webservice deve apenas utf-8 codificá-lo e devolvê-lo, ou ele deveria escapar de todos os caracteres não ascii e retornar ascii puro?

Eu gostaria que os navegadores pudessem executar os resultados usando jsonp ou eval. Isso afeta a decisão? Meu conhecimento do suporte javascript de vários navegadores para utf-8 está faltando.

EDIT: Eu queria esclarecer que a minha principal preocupação sobre como codificar os resultados é realmente sobre o manuseio do navegador dos resultados. O que eu li indica que os navegadores podem ser sensíveis à codificação ao usar o JSONP em particular. Eu não encontrei nenhuma informação realmente boa sobre o assunto, então vou ter que começar a fazer alguns testes para ver o que acontece. Idealmente, eu gostaria apenas de escapar daqueles poucos caracteres que são necessários e apenas utf-8 codificar os resultados.

77
schickb

A especificação JSON requer Suporte UTF-8 por decodificadores. Como resultado, todos os decodificadores JSON podem manipular o UTF-8 tão bem quanto eles podem manipular as seqüências numéricas de escape. Esse também é o caso dos intérpretes de Javascript, o que significa que o JSONP também lidará com o JSON codificado em UTF-8.

A capacidade dos codificadores JSON de usar as seqüências numéricas de escape apenas oferece mais opções. Uma razão pela qual você pode escolher as seqüências de escape numéricas seria se um mecanismo de transporte entre seu codificador e o decodificador pretendido não é seguro para binário.

Outro motivo pelo qual você pode querer usar sequências de escape numéricas é impedir que determinados caracteres apareçam no fluxo, como <, & e ", que podem ser interpretados como sequências HTML se o código JSON for colocado sem escapar para HTML ou um navegador interpretar incorretamente como HTML. Isso pode ser uma defesa contra injeção de HTML ou scripts entre sites (note: alguns caracteres DEVEM ter escape em JSON, incluindo " e \).

Algumas estruturas, incluindo a implementação do JSON no PHP, sempre fazem as seqüências numéricas de escape no lado do codificador para qualquer caractere fora do ASCII. Isso é destinado a compatibilidade máxima com mecanismos de transporte limitados e similares. No entanto, isso não deve ser interpretado como uma indicação de que os decodificadores JSON têm um problema com o UTF-8.

Então, eu acho que você só poderia decidir qual usar assim:

  • Basta usar o UTF-8, a menos que seu método de armazenamento ou transporte entre o codificador e o decodificador não seja seguro para binário.

  • Caso contrário, use as seqüências de escape numéricas.

75
thomasrutter

Eu tive um problema aí. Quando eu JSON codificar uma string com um caractere como "é", todos os navegadores retornarão o mesmo "é", exceto IE que retornará "\ u00e9".

Então com PHP json_decode (), ele irá falhar se encontrar "é", então para Firefox, Opera, Safari e Chrome, eu tenho que chamar utf8_encode () antes de json_decode ().

Nota: com meus testes, IE e o Firefox estão usando seu objeto JSON nativo, outros navegadores estão usando o json2.js.

15
Olivier

ASCII não está mais presente. Usar a codificação UTF-8 significa que você não está usando a codificação ASCII. O que você deve usar o mecanismo de escape é o que o RFC diz:

Todos os caracteres Unicode podem ser colocados entre aspas, exceto os caracteres que devem ter escape: aspas, solidus reverso e os caracteres de controle (U + 0000 a U + 001F)

12
chaos

Eu estava enfrentando o mesmo problema. Funciona para mim. Por favor, checar isto.

json_encode($array,JSON_UNESCAPED_UNICODE);
7
Ankit Sewadik

Lendo o json rfc ( http://www.ietf.org/rfc/rfc4627.txt ) está claro que a codificação preferida é utf-8.

FYI, RFC 4627 não é mais a especificação JSON oficial. Ele ficou obsoleto em 2014 por RFC 7159 , que foi então obsoleto em 2017 por RFC 8259 , que é a especificação atual.

RFC 8259 afirma:

8.1. Codificação de caracteres

Texto JSON trocado entre sistemas que não fazem parte de um ecossistema fechado deve ser codificado usando UTF-8 [RFC3629] .

Especificações anteriores de JSON não exigiram o uso de UTF-8 ao transmitir texto JSON. No entanto, a grande maioria das implementações de software baseadas em JSON optou por usar a codificação UTF-8, na medida em que é a única codificação que alcança a interoperabilidade.

Implementações NÃO DEVEM adicionar uma marca de ordem de byte (U + FEFF) ao início de um texto JSON transmitido em rede. No interesse da interoperabilidade, implementações que analisam textos JSON podem ignorar a presença de uma marca de ordem de byte em vez de tratá-la como um erro.

1
Remy Lebeau

Eu tive um problema semelhante com é char ... Eu acho que o comentário "é possível que o texto que você está alimentando não é UTF-8" é provavelmente próximo da marca aqui. Eu tenho a sensação de que o agrupamento padrão na minha instância era outra coisa até que percebi e mudei para utf8 ... problema é que os dados já estavam lá, então não tenho certeza se converteu os dados ou não quando eu mudei, exibe bem no mysql bancada de trabalho. O resultado final é que o php não irá codificar os dados, apenas retorna false. Não importa qual navegador você usa como seu servidor causando o meu problema, o php não irá analisar os dados para utf8 se este char estiver presente. Como eu digo não tenho certeza se é devido a converter o esquema para utf8 após os dados estarem presentes ou apenas um bug php. Neste caso, use json_encode(utf8_encode($string));

0
Paul Smith