web-dev-qa-db-fra.com

Gestion sécurisée de JSON.parse () dans le noeud en toute sécurité

Utilisation de node/express - Je souhaite extraire des en-têtes de requête JSON, mais je souhaite le faire en toute sécurité.
Si, pour une raison quelconque, JSON n’est pas valide, c’est acceptable, il peut simplement renvoyer false ou quoi que ce soit et il rejettera simplement la demande et continuera. Le problème est qu'il génère une erreur de syntaxe s'il ne s'agit pas d'un code JSON valide. Normalement, je veux qu'une erreur de syntaxe explose, mais pas dans ce cas.

var boom = JSON.parse(req.headers.myHeader);

Dois-je gratter la pile et rechercher un appel d'analyse incorrect à partir de ce module particulier, et si c'est le cas, il l'ignore? Cela semble un peu fou. Il y a sûrement un meilleur moyen.

EDIT: Je suis conscient que les blocs try/catch sontUNmoyen de gérer cette erreur, mais est-ce la meilleure manière dans une application de nœud? Est-ce que cela va bloquer le noeud?

22
tpie

Le meilleur moyen de détecter les erreurs d’analyse JSON non valides consiste à placer les appels dans JSON.parse() dans un bloc try/catch.

Vous n'avez vraiment aucune autre option - l'implémentation intégrée lève une exception sur les données JSON non valides et le seul moyen d'empêcher cette exception d'arrêter votre application est de l'intercepter. Même si vous utilisez une bibliothèque tierce, cela ne vous évitera pas - ils doivent faire un try/catch lors d'un appel JSON.parse() quelque part.

La seule alternative est d'implémenter votre propre algorithme d'analyse JSON qui pourrait être plus tolérant pour les structures de données non valides, mais cela donne l'impression de creuser un trou de 1 mètre cube avec une petite clé nucléaire.

Note sur les performances

Le moteur JavaScript v8 utilisé par Node.js ne peut pas optimiser les fonctions contenant un bloc try/catch

Mise à jour:v8 4.5 et supérieur peut optimiser try/catch . Pour les versions plus anciennes, voir ci-dessous.

Une solution de contournement simple consiste à placer la logique d'analyse sécurisée dans une fonction distincte de sorte que la fonction principale puisse toujours être optimisée:

function safelyParseJSON (json) {
  // This function cannot be optimised, it's best to
  // keep it small!
  var parsed

  try {
    parsed = JSON.parse(json)
  } catch (e) {
    // Oh well, but whatever...
  }

  return parsed // Could be undefined!
}

function doAlotOfStuff () {
  // ... stuff stuff stuff
  var json = safelyParseJSON(data)
  // Tadaa, I just got rid of an optimisation killer!
}

Si l'analyse JSON est effectuée de manière sporadique, cela peut ne pas avoir d'effet notable sur les performances, mais si vous l'utilisez de manière incorrecte dans une fonction d'utilisation intensive, les temps de réponse peuvent être considérablement augmentés.

Note sur le blocage de try/catch

Il est à noter que every.single.statement du code JavaScript dans Node.js est exécuté uniquement un par un, qu'il soit appelé depuis la fonction principale, depuis un rappel ou depuis un module différent. ou peu importe. En tant que tel, chaque déclaration bloquera le processus. Ce n'est pas nécessairement une mauvaise chose: une application bien conçue passera la plupart de son temps à attendre une ressource externe (réponse à la base de données, communication HTTP, opérations du système de fichiers, etc.). Il est donc très important que le code JavaScript fréquemment exécuté puisse être optimisé par le moteur v8 afin qu’il prenne le moins de temps possible dans cet état bloqué - voir la note sur les performances.

49
Robert Rossmann

Vous pouvez utiliser try et catch

function parseMyHeader(){
    try {
      return JSON.parse(req.headers.myHeader);
    } catch(ex){
      return null;
    }
}
7
EJTH

La méthode standard try/catch est le moyen approprié de gérer une erreur JSON.parse dans node.js, comme indiqué dans le noeud pratiques de production pour la gestion des erreurs docs du site Web joyent, qui indique:

... Le seul cas couramment utilisé où vous utiliseriez try/catch est JSON.parse et d'autres fonctions de validation entrées par l'utilisateur.

Ce qui est également en accord avec le lien vers nodejitsu que Aleksandr a fourni dans son commentaire.

3
tpie

Ceci est sur la façon de ne pas casser le script pendant une exception

Promise.resolve((body)=>{
            let fbResponse = JSON.parse(body);
            // some code for good
        }).catch(error => {
            cl('Parsing error:');
            cl(error);
            // some code for bad
        });
0
user3640561
        var parsed;

        try {
            parsed = JSON.parse(data);
        } catch (e) {
            parsed = JSON.parse(JSON.stringify(data));
        }

        root = parsed;

Eh bien, cela a fonctionné pour moi . Dans Catch, j'ai converti les données en chaînes avant de les analyser en JSON.

0
Ganesh Todkar