Accueil > JavaScript > Prototype et les interpréteurs JSON natifs des navigateurs : NATIVE_JSON_PARSE_SUPPORT

Prototype et les interpréteurs JSON natifs des navigateurs : NATIVE_JSON_PARSE_SUPPORT

J’ai aujourd’hui expérimenté un curieux problème en essayant de mettre à jour Prototype sur un site web. Du code qui fonctionnait bien, subitement, ne fonctionnait plus avec la version 1.7.

En cherchant bien, j’ai fini pas comprendre qu’il y avait un problème avec du code JSON. Or, à première vue, ce code paraissait tout à fait correct :

{
	mode : "exact",
	elements : "textarea_bouzi_txt_index_para_1",
	theme : "advanced",
	skin : "o2k7",
	plugins : "",
	theme_advanced_toolbar_location : "top",
	theme_advanced_toolbar_align : "left",
	theme_advanced_statusbar_location : "bottom",
	convert_urls : false,
	relative_urls : false,
	forced_root_block : false,
	extended_valid_elements : "div[*],iframe[*]"
}

Pourquoi cela ne fonctionnait-il pas alors ? C’est qu’en y regardant de plus près, on voit qu’il n’est pas correct : les propriétés ne sont pas entre guillemets. Ce code (qui provient je crois de TinyMCE - c’est à vérifier) devrait donc plutôt être :

{
	"mode" : "exact",
	"elements" : "textarea_bouzi_txt_index_para_1",
	"theme" : "advanced",
	"skin" : "o2k7",
	"plugins" : "",
	"theme_advanced_toolbar_location" : "top",
	"theme_advanced_toolbar_align" : "left",
	"theme_advanced_statusbar_location" : "bottom",
	"convert_urls" : false,
	"relative_urls" : false,
	"forced_root_block" : false,
	"extended_valid_elements" : "div[*],iframe[*]"
}

Reste que cela n’explique pas pourquoi ce code, aussi erroné soit-il, ne fonctionnait subitement plus.

La réponse est que les navigateurs récents implémentent désormais d’une manière native le propre interpréteur JSON. Plus besoin de passer par une bibliothèque JavaScript JSON ; on fait simplement :

JSON.parse('["du code JSON"]');

Or, dans sa dernière version, Prototype essaye de s’appuyer sur l’interpréteur JSON natif du navigateur quand il en existe un, ceci à des fins de performance. Mais c’est là qu’il y a un problème : cet interpréteur est en général beaucoup plus rigoureux. J’ai en effet essayé avec Firefox 3.6 et Internet Explorer 9.0, et dans les deux cas, le code JSON qui n’utilise pas de guillemets pour les propriétés provoque une erreur.

Au sens strict, on ne peut pas parler d’un bug de ces interpréteurs, car le code JSON est effectivement mal formé. Cependant, il existe un grand nombre de bibliothèques qui ne rendent pas un code JSON avec les propriétés entre guillemets (comme apparemment la version de TinyMCE que j’utilise). Tout ce code fera immanquablement planter la dernière version de Prototype, ce qui est problématique.

La meilleure solution consisterait à fournir du code JSON bien formé à Prototype, mais ce n’est pas toujours possible. Reste alors une autre solution simple, consistant à downgrader prototype afin qu’il ne cherche pas à utiliser le parser natif du navigateur lorsqu’il y en a un, et le forcer à utiliser son propre interpréteur.

Pour ce faire, il y a plusieurs solutions, qui nécessitent toutes de modifier un peu le fichier prototype.js. Je les liste par ordre de préférence personnelle :

  • Remplacer la ligne 772 par :
    evalJSON: evalJSON,
  • Remplacer le bloc des lignes 535-537 par :
    var NATIVE_JSON_PARSE_SUPPORT = false;
  • Remplacer le bloc des lignes 718-721 par :
    function parseJSON() {
        var json = this.unfilterJSON();
        return evalJSON(json);
    }

Faites votre propre choix ! Même si la meilleure solution reste d’avoir du code JSON propre dès le départ :)

  1. Pas encore de commentaire
  1. Pas encore de trackbacks