J'essaie de comprendre ce qui ne va pas avec ma sérialisation json, j'ai la version actuelle de mon application avec une ancienne et je trouve des différences surprenantes dans le fonctionnement de JSON.stringify () (en utilisant la bibliothèque JSON de json.org ).
Dans l'ancienne version de mon application:
JSON.stringify({"a":[1,2]})
me donne ceci;
"{\"a\":[1,2]}"
dans la nouvelle version,
JSON.stringify({"a":[1,2]})
me donne ceci;
"{\"a\":\"[1, 2]\"}"
une idée de ce qui aurait pu changer pour que la même bibliothèque place des guillemets autour des crochets du tableau dans la nouvelle version?
javascript
json
prototypejs
Morgancodes
la source
la source
Réponses:
Étant donné que JSON.stringify a été livré avec certains navigateurs récemment, je suggère de l'utiliser à la place du toJSON de Prototype. Vous vérifieriez alors window.JSON && window.JSON.stringify et n'incluriez que la bibliothèque json.org sinon (via
document.createElement('script')
…). Pour résoudre les incompatibilités, utilisez:la source
La fonction JSON.stringify () définie dans ECMAScript 5 et supérieur (Page 201 - l'objet JSON, pseudo-code Page 205) , utilise la fonction toJSON () lorsqu'elle est disponible sur les objets.
Étant donné que Prototype.js (ou une autre bibliothèque que vous utilisez) définit une fonction Array.prototype.toJSON (), les tableaux sont d'abord convertis en chaînes à l'aide de Array.prototype.toJSON () puis une chaîne citée par JSON.stringify (), d'où le guillemets supplémentaires incorrects autour des tableaux.
La solution est donc simple et triviale (il s'agit d'une version simplifiée de la réponse de Raphael Schweikert):
Cela produit bien sûr des effets secondaires sur les bibliothèques qui reposent sur une propriété de fonction toJSON () pour les tableaux. Mais je trouve cela un inconvénient mineur compte tenu de l'incompatibilité avec ECMAScript 5.
Il faut noter que l'objet JSON défini dans ECMAScript 5 est efficacement implémenté dans les navigateurs modernes et que la meilleure solution est donc de se conformer au standard et de modifier les bibliothèques existantes.
la source
Une solution possible qui n'affectera pas les autres dépendances de Prototype serait:
Cela prend en charge l'incompatibilité Array toJSON avec JSON.stringify et conserve également la fonctionnalité toJSON car d'autres bibliothèques de prototypes peuvent en dépendre.
la source
if(typeof Prototype !== 'undefined' && parseFloat(Prototype.Version.substr(0,3)) < 1.7 && typeof Array.prototype.toJSON !== 'undefined')
. Ça a marché.Modifiez pour rendre un peu plus précis:
Le bit de code clé du problème se trouve dans la bibliothèque JSON de JSON.org (et d'autres implémentations de l'objet JSON d'ECMAScript 5):
Le problème est que la bibliothèque Prototype étend Array pour inclure une méthode toJSON, que l'objet JSON appellera dans le code ci-dessus. Lorsque l'objet JSON atteint la valeur du tableau, il appelle toJSON sur le tableau qui est défini dans Prototype, et cette méthode retourne une version chaîne du tableau. Par conséquent, les guillemets autour des crochets du tableau.
Si vous supprimez toJSON de l'objet Array, la bibliothèque JSON devrait fonctionner correctement. Ou, utilisez simplement la bibliothèque JSON.
la source
Je pense qu'une meilleure solution serait de l'inclure juste après le chargement du prototype
Cela rend la fonction prototype disponible en tant que JSON.stringify () et JSON.parse () standard, mais conserve le JSON.parse () natif s'il est disponible, ce qui rend les choses plus compatibles avec les navigateurs plus anciens.
la source
Je ne maîtrise pas très bien Prototype, mais j'ai vu cela dans ses documents :
Je ne suis pas sûr que cela pose le même problème que l'encodage actuel.
Il existe également un didacticiel plus long sur l'utilisation de JSON avec Prototype.
la source
C'est le code que j'ai utilisé pour le même problème:
Vous vérifiez si Prototype existe, puis vous vérifiez la version. Si l'ancienne version utilise Object.toJSON (si est défini) dans tous les autres cas, retournez à JSON.stringify ()
la source
Voici comment je gère ça.
la source
Ma solution tolérante vérifie si Array.prototype.toJSON est nocif pour JSON stringify et le conserve lorsque cela est possible pour laisser le code environnant fonctionner comme prévu:
la source
Comme les gens l'ont souligné, cela est dû à Prototype.js - en particulier aux versions antérieures à la 1.7. J'avais une situation similaire mais je devais avoir un code qui fonctionnait, que Prototype.js soit là ou non; cela signifie que je ne peux pas simplement supprimer Array.prototype.toJSON car je ne suis pas sûr de ce qui en dépend. Pour cette situation, c'est la meilleure solution que j'ai trouvée:
J'espère que cela aidera quelqu'un.
la source
Si vous ne voulez pas tout tuer et avoir un code qui convient à la plupart des navigateurs, vous pouvez le faire de cette façon:
Cela semble complexe, mais cela n'est complexe que pour gérer la plupart des cas d'utilisation. L'idée principale est
JSON.stringify
de supprimertoJSON
de l'objet passé en argument, puis d'appeler l'ancienJSON.stringify
et enfin de le restaurer.la source