202 votes

Comment vérifier si la réponse d'un fetch est un objet json en javascript ?

J'utilise le polyfill fetch pour récupérer un JSON ou du texte à partir d'une URL. Je veux savoir comment vérifier si la réponse est un objet JSON ou s'il s'agit uniquement de texte.

fetch(URL, options).then(response => {
   // how to check if response has a body of type json?
   if (response.isJson()) return response.json();
});

0 votes

324voto

nils Points 11708

Vous pourriez vérifier si le content-type de la réponse, comme indiqué dans cet exemple MDN :

fetch(myRequest).then(response => {
  const contentType = response.headers.get("content-type");
  if (contentType && contentType.indexOf("application/json") !== -1) {
    return response.json().then(data => {
      // process your JSON data further
    });
  } else {
    return response.text().then(text => {
      // this is text, do something with it
    });
  }
});

Si vous avez besoin d'être absolument sûr que le contenu est du JSON valide (et que vous ne faites pas confiance aux en-têtes), vous pouvez toujours accepter la réponse en tant que text et l'analyser vous-même :

fetch(myRequest)
  .then(response => response.text())
  .then(text => {
    try {
        const data = JSON.parse(text);
        // Do your JSON handling here
    } catch(err) {
       // It is text, do you text handling here
    }
  });

Async/await

Si vous utilisez async/await vous pourriez l'écrire d'une manière plus linéaire :

async function myFetch(myRequest) {
  try {
    const reponse = await fetch(myRequest); // Fetch the resource
    const text = await response.text(); // Parse it as text
    const data = JSON.parse(text); // Try to parse it as json
    // Do your JSON handling here
  } catch(err) {
    // This probably means your response is text, do you text handling here
  }
}

1 votes

Avec la même stratégie, vous pourriez simplement utiliser response.json en combinaison avec catch ; si vous attrapez une erreur, cela signifie que ce n'est pas json. Ne serait-ce pas une façon plus idiomatique de gérer ce problème (au lieu d'abandonner response.json) ?

12 votes

@WouterRonteltap : N'êtes-vous pas seulement autorisé à faire l'un ou l'autre. Il me semble me souvenir que vous n'avez droit qu'à un seul essai avec response.anything(). Si c'est le cas, JSON est du texte, mais le texte n'est pas nécessairement JSON. Par conséquent, vous devez commencer par la solution la plus sûre, à savoir .text(). Si vous faites d'abord .json(), et que cela échoue, je ne pense pas que vous aurez l'occasion de faire également .text(). Si je me trompe, montrez-moi le contraire.

3 votes

À mon avis, vous ne pouvez pas faire confiance aux en-têtes (même si vous devriez, mais parfois vous ne pouvez pas contrôler le serveur de l'autre côté). C'est donc une bonne chose que vous mentionniez également try-catch dans votre réponse.

18voto

larskarbo Points 83

Vous pouvez le faire proprement avec une fonction d'aide :

const parseJson = async response => {
  const text = await response.text()
  try{
    const json = JSON.parse(text)
    return json
  } catch(err) {
    throw new Error("Did not receive JSON, instead received: " + text)
  }
}

Et ensuite l'utiliser comme ça :

fetch(URL, options)
.then(parseJson)
.then(result => {
    console.log("My json: ", result)
})

Cela entraînera une erreur et vous pourrez catch si vous le souhaitez.

0voto

Rakesh Soni Points 913

Utilisez un analyseur JSON comme JSON.parse :

function IsJsonString(str) {
    try {
        var obj = JSON.parse(str);

         // More strict checking     
         // if (obj && typeof obj === "object") {
         //    return true;
         // }

    } catch (e) {
        return false;
    }
    return true;
}

-1voto

Saeid Alidadi Points 406

J'ai récemment publié un npm paquet qui comprend des fonctions utilitaires communes. L'une de ces fonctions que j'ai implémentée ici est juste comme la nis 's async/await réponse que vous pouvez utiliser comme ci-dessous :

import {fetchJsonRes, combineURLs} from "onstage-js-utilities";

fetch(combineURLs(HOST, "users"))
    .then(fetchJsonRes)
    .then(json => {
        // json data
    })
    .catch(err => {
        // when the data is not json
    })

vous pouvez trouver la source sur Github

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X