Estou tentando descobrir o que há de errado com minha serialização json, tenho a versão atual do meu aplicativo com uma antiga e estou encontrando algumas diferenças surpreendentes na maneira como JSON.stringify () funciona (usando a biblioteca JSON de json.org )
Na versão antiga do meu aplicativo:
JSON.stringify({"a":[1,2]})
me dá isso;
"{\"a\":[1,2]}"
na nova versão,
JSON.stringify({"a":[1,2]})
me dá isso;
"{\"a\":\"[1, 2]\"}"
alguma ideia do que poderia ter mudado para fazer a mesma biblioteca colocar aspas entre os colchetes do array na nova versão?
javascript
json
prototypejs
morgancodes
fonte
fonte
Respostas:
Como JSON.stringify tem sido enviado com alguns navegadores recentemente, eu sugeriria usá-lo em vez do toJSON do Prototype. Você deve então verificar por window.JSON && window.JSON.stringify e incluir apenas a biblioteca json.org de outra forma (via
document.createElement('script')
…). Para resolver as incompatibilidades, use:fonte
A função JSON.stringify () definida no ECMAScript 5 e acima (Página 201 - o objeto JSON, pseudo-código Página 205) , usa a função toJSON () quando disponível nos objetos.
Como Prototype.js (ou outra biblioteca que você está usando) define uma função Array.prototype.toJSON (), os arrays são primeiro convertidos em strings usando Array.prototype.toJSON (), em seguida, string citada por JSON.stringify (), daí o citações extras incorretas em torno dos arrays.
A solução é, portanto, direta e trivial (esta é uma versão simplificada da resposta de Raphael Schweikert):
Obviamente, isso produz efeitos colaterais em bibliotecas que dependem de uma propriedade de função toJSON () para matrizes. Mas acho isso um pequeno inconveniente, considerando a incompatibilidade com ECMAScript 5.
Deve-se observar que o objeto JSON definido no ECMAScript 5 é implementado de forma eficiente em navegadores modernos e, portanto, a melhor solução é se conformar ao padrão e modificar as bibliotecas existentes.
fonte
Uma possível solução que não afetará outras dependências do protótipo seria:
Isso cuida da incompatibilidade de Array toJSON com JSON.stringify e também retém a funcionalidade toJSON, pois outras bibliotecas de Prototype podem depender dela.
fonte
if(typeof Prototype !== 'undefined' && parseFloat(Prototype.Version.substr(0,3)) < 1.7 && typeof Array.prototype.toJSON !== 'undefined')
. Funcionou.Edite para tornar um pouco mais preciso:
O código-chave do problema está na biblioteca JSON de JSON.org (e outras implementações do objeto JSON do ECMAScript 5):
O problema é que a biblioteca Prototype estende Array para incluir um método toJSON, que o objeto JSON chamará no código acima. Quando o objeto JSON atinge o valor da matriz, ele chama toJSON na matriz definida em Prototype e esse método retorna uma versão de string da matriz. Portanto, as aspas entre os colchetes da matriz.
Se você excluir toJSON do objeto Array, a biblioteca JSON deverá funcionar corretamente. Ou apenas use a biblioteca JSON.
fonte
Acho que uma solução melhor seria incluir isso logo após o protótipo ser carregado
Isso disponibiliza a função de protótipo como JSON.stringify () e JSON.parse () padrão, mas mantém o JSON.parse () nativo se estiver disponível, portanto, torna as coisas mais compatíveis com navegadores mais antigos.
fonte
Não sou tão fluente com Prototype, mas vi isso em seus documentos :
Não tenho certeza se isso teria o mesmo problema que a codificação atual tem, no entanto.
Há também um tutorial mais longo sobre como usar JSON com Prototype.
fonte
Este é o código que usei para o mesmo problema:
Você verifica se o Prototype existe, então verifica a versão. Se a versão antiga usar Object.toJSON (se estiver definido) em todos os outros casos, fallback para JSON.stringify ()
fonte
É assim que estou lidando com isso.
fonte
Minha solução tolerante verifica se Array.prototype.toJSON é prejudicial para JSON stringify e o mantém, quando possível, para permitir que o código circundante funcione conforme o esperado:
fonte
Como as pessoas apontaram, isso se deve ao Prototype.js - especificamente às versões anteriores a 1.7. Eu tive uma situação semelhante, mas precisava de um código que funcionasse independentemente de o Prototype.js estar lá ou não; isso significa que não posso simplesmente excluir o Array.prototype.toJSON, pois não tenho certeza do que depende dele. Para essa situação, esta é a melhor solução que encontrei:
Espero que ajude alguém.
fonte
Se você não quiser matar tudo e tiver um código que funcionaria na maioria dos navegadores, pode fazer desta forma:
Isso parece complexo, mas é complexo apenas para lidar com a maioria dos casos de uso. A ideia principal é substituir
JSON.stringify
para removertoJSON
do objeto passado como um argumento, chamar o antigoJSON.stringify
e finalmente restaurá-lo.fonte