ReadableStream nesnesinden veri alınsın mı?


136

Bir ReadableStreamnesneden nasıl bilgi alabilirim ?

Getirme API'sını kullanıyorum ve bunun belgelerden anlaşılır olduğunu görmüyorum.

Gövde bir olarak iade ediliyor ReadableStreamve bu akış içindeki bir özelliğe erişmek istiyorum. Tarayıcı geliştirme araçlarındaki Yanıt altında, bu bilgilerin bir JavaScript nesnesi biçiminde özellikler halinde düzenlenmiş gibi görünüyor.

fetch('http://192.168.5.6:2000/api/car', obj)
    .then((res) => {
        if(res.status == 200) {
            console.log("Success :" + res.statusText);   //works just fine
        }
        else if(res.status == 400) {
            console.log(JSON.stringify(res.body.json());  //res.body is undefined.
        }

        return res.json();
    })


2
@FrancescoPezzella Cevabınız için teşekkürler. Denedim response.Body.json(), ancak italik TypeError alıyorum : Tanımlanmamış italik 'json' özelliği okunamıyor . Bunun nedeni bodyUsed özelliğinin de false değerine ayarlanmış olması mı? Ancak bu gövdeyi tarayıcı geliştirici araçlarındaki yanıt sekmesinin altında görüntüleyebilirim. Almak istediğim bir hata mesajı var.
noob

Yani sorununuz tamamen 400 hatası durumuyla mı ilgili? İşleyiciyi olarak değiştirirseniz ne olur console.log(res.json());? Beklediğiniz verileri görüyor musunuz?
Ashley 'CptLemming' Wilson

@noob Yanıtı bir akış olarak okumaya mı çalışıyorsunuz res.status == 200?
misafir271314

Sadece ben ya dokümantasyon olmasıdır düz yanlış? Yine de bu cevaplardaki çözümlerle düzelttim.
Lucio

Yanıtlar:


177

Verilere a'dan erişmek için ReadableStreamdönüştürme yöntemlerinden birini çağırmanız gerekir (belgeler burada mevcuttur ).

Örnek olarak:

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(function(response) {
    // The response is a Response instance.
    // You parse the data into a useable format using `.json()`
    return response.json();
  }).then(function(data) {
    // `data` is the parsed version of the JSON returned from the above endpoint.
    console.log(data);  // { "userId": 1, "id": 1, "title": "...", "body": "..." }
  });

DÜZENLEME: Veri dönüş türünüz JSON değilse veya JSON istemiyorsanıztext()

Örnek olarak:

fetch('https://jsonplaceholder.typicode.com/posts/1')
  .then(function(response) {
    return response.text();
  }).then(function(data) {
    console.log(data); // this will be a string
  });

Umarım bu, işleri düzeltmeye yardımcı olur.


1
Cevabınız için teşekkürler. Bunu denedim ve hala res.body'nin tanımsız olduğu aynı hatayı alıyorum. Ancak önce res.status ile () işlevinde durumu geri alabiliyorum. Görünüşe göre yalnızca gövde bir ReadableStream nesnesidir. Doğru olarak ayarlanmış kilitli bir özelliği var gibi görünüyor?
noob

Nereye erişmeye çalışıyorsunuz res.body(bu benim örneğimin bir parçası değil)? Sorununuzun nerede olabileceğini daha net hale getirmek için orijinal sorunuzda bazı örnek kodlar paylaşabilir misiniz?
Ashley 'CptLemming' Wilson

1
İlk .then () işlevinde döndürülen json yanıtından res.body'ye erişmeyi denedim. Daha fazla netlik için orijinal soruma bir örnek ekledim. Teşekkürler!
noob

1
Harika, react ve request native kullanarak ve ReadableStream ile dünyada ne yapılacağını merak ederek ve bu hile yaptı. ++
edencorbin

Sadece bir uyarı, çok basit gibi görünüyor, ancak vurduğunuz arka ucun gerçekten geçerli JSON sağladığından emin olun! Kesinlikle deneyimden bahsetmiyorum.
abelito

45

Bazı insanlar bir asyncörneği faydalı bulabilir :

var response = await fetch("https://httpbin.org/ip");
var body = await response.json(); // .json() is asynchronous and therefore must be awaited

json()yanıtın gövdesini ReadableStreama'dan json nesnesine dönüştürür.

awaitİfadeleri bir sarılmış olmalıdır asyncancak çalıştırabileceğiniz, fonksiyonu await(versiyonunda 62 itibariyle) Chrome konsolda doğrudan ifadeleri.


1
Bazen sizin için gerçek cevap gerçekten 2 numara haha, neden .json () 'ı eşzamansız yaptıkları mantıklıdır, ancak hemen açık değildi
Sanchit Batra

29

res.json()bir söz verir. Deneyin ...

res.json().then(body => console.log(body));

3
Bunu denedim ve vücut yerine Sözün çıktısını aldım.
reectrix

.thenÇağrıları zincirlemeye çalışın :fetch(...).then(res => res.json()).then(data => console.log(data))
Óscar Gómez Alcañiz

12

Partiye biraz geç kaldı, ancak ReadableStreamSharepoint Çerçevesi kullanılarak bir Odata $ toplu isteğinden üretilen birinden yararlı bir şey elde etmede bazı sorunlar yaşadım.

OP ile benzer sorunlar vardı, ancak benim durumumdaki çözüm, bundan farklı bir dönüştürme yöntemi kullanmaktı .json(). Benim durumumda .text()bir cazibe gibi çalıştı. Bununla birlikte, metin dosyasından bazı yararlı JSON almak için biraz uğraşmak gerekiyordu.


2
Teşekkür ederim! Bu benim için çalıştı. Basit bir şekilde Laravel sunucumdan bir Illuminate http yanıtı gönderiyorum return $data;. Sonunda bu yanıtı tarayıcıdafetch(...).then(response => response.text()).then(data => console.log(data));
Cameron Hudson

10

Yanıtı yalnızca metin olarak istiyorsanız ve JSON'a dönüştürmek istemiyorsanız, https://developer.mozilla.org/en-US/docs/Web/API/Body/text adresini kullanın ve ardından thenasıl sözün sonucu:

fetch('city-market.md')
  .then(function(response) {
    response.text().then((s) => console.log(s));
  });

veya

fetch('city-market.md')
  .then(function(response) {
    return response.text();
  })
  .then(function(myText) {
    console.log(myText);
  });

2

Zincirlemekten hoşlanmıyorum. İkincisi daha sonra duruma erişemez. Daha önce belirtildiği gibi 'response.json ()' bir söz verir. Ardından, 'response.json ()' sonucunu bir saniyeye benzer bir eylemde döndürmek. Yanıt kapsamında olmanın ek bonusuna sahiptir.

return fetch(url, params).then(response => {
    return response.json().then(body => {
        if (response.status === 200) {
            return body
        } else {
            throw body
        }
    })
})

Zincirleme then, nihai çözümlenmiş değeri almanıza yardımcı olur (body ) . Bunları iç içe yerleştirmek, bodybir geri arama veya sıralama mekanizması olmadan değeri almanızı engeller . Bu hayal: let body = await fetch(...).then(res => res.json()).then(data => data). Bu iç içe geçmiş şekilde çalışmaz. Sizi kontrol etmek için response.statusher zaman throwilkinin içinde bir istisna olabilir ve tüm söz zincirine thenbir ekleyebilirsiniz catch.
Óscar Gómez Alcañiz

0

Bir akışı yalnızca bir kez okuyabileceğinizi unutmayın, bu nedenle bazı durumlarda, tekrar tekrar okumak için yanıtı klonlamanız gerekebilir:

fetch('example.json')
  .then(res=>res.clone().json())
  .then( json => console.log(json))

fetch('url_that_returns_text')
  .then(res=>res.clone().text())
  .then( text => console.log(text))
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.