Bir getirmenin yanıtının javascript'te bir json nesnesi olup olmadığı nasıl kontrol edilir


107

Bir URL'den bir JSON veya metin almak için çoklu dolguyu getir kullanıyorum, yanıtın bir JSON nesnesi mi yoksa yalnızca metin mi olduğunu nasıl kontrol edebileceğimi bilmek istiyorum

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

Yanıtlar:


182

Bu MDN örneğindecontent-type gösterildiği gibi yanıtı kontrol edebilirsiniz :

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
    });
  }
});

İçeriğin geçerli JSON olduğundan kesinlikle emin olmanız gerekiyorsa (ve başlıklara güvenmiyorsanız), yanıtı her zaman olarak kabul edebilir textve kendiniz ayrıştırabilirsiniz:

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 / bekleme

Kullanıyorsanız async/await, daha doğrusal bir şekilde yazabilirsiniz:

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
Aynı strateji ile response.json'u catch ile birlikte kullanabilirsiniz; bir hata yakalarsanız, bunun json olmadığı anlamına gelir. Bu, bunu halletmenin daha deyimsel bir yolu olmaz mıydı (response.json'dan kurtulmak yerine)?
Wouter Ronteltap

4
@WouterRonteltap: Sadece birini veya diğerini yapmanıza izin verilmiyor mu? Görünüşe göre yanıtta sadece bir şansınız olduğunu hatırlıyorum. Her şey (). Öyleyse, JSON metindir, ancak metin mutlaka JSON değildir. Bu nedenle, önce kesin olanı yapmalısınız, yani .text (). Önce .json () yaparsanız ve başarısız olursa, .text () yapma fırsatını da elde edeceğinizi sanmıyorum. Eğer yanılıyorsam, lütfen bana farklı göster.
Lonnie Best

3
Bana göre başlıklara güvenemezsiniz (gerekse bile, ancak bazen diğer taraftaki sunucuyu kontrol edemezsiniz). Bu yüzden cevabınızda dene-yakala'dan da bahsetmeniz harika.
Jacob

2
Evet, @Lonnie Best bu konuda tamamen doğrudur. .json () 'ı çağırırsanız ve bir istisna atarsa ​​(çünkü yanıt json değildir), daha sonra .text ()' i çağırırsanız bir "Gövde zaten tüketildi" istisnası alırsınız
Andy,

4

Bunu bir yardımcı işlevle temiz bir şekilde yapabilirsiniz:

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)
  }
}

Ve sonra şu şekilde kullanın:

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

Bu bir hata atar, böylece isterseniz yapabilirsiniz catch.


1

JSON.parse gibi bir JSON ayrıştırıcısı kullanın:

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;
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.