Отримати дані з об’єкта ReadableStream?


135

Як я можу отримати інформацію від ReadableStreamоб'єкта?

Я використовую API Fetch, і я не бачу цього в документації.

Тіло повертається як ReadableStreamі я просто хотів би отримати доступ до ресурсу в цьому потоці. У розділі Відповідь у інструментах для розробників браузера я, схоже, цю інформацію організував у властивості у вигляді об’єкта JavaScript.

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 Дякую за відповідь. Я спробував response.Body.json(), але я отримую курсив TypeError: Не вдається прочитати властивість 'json' невизначеного курсиву . Це тому, що властивість bodyUsed також встановлено на false? Однак я можу переглядати цей орган на вкладці відповідей у ​​інструментах для розробників браузера. Є повідомлення про помилку, яке я хотів би отримати.
noob

Отже, ваше питання суто пов'язане з умовою помилки 400? Що станеться, якщо змінити обробник на console.log(res.json());? Чи бачите ви очікувані дані?
Ashley 'CptLemming' Wilson

@noob Ви намагаєтесь прочитати відповідь як потік, якщо res.status == 200?
гість271314

Це просто я чи ця документація явно невірна? Я все-таки полагодив це рішеннями на ці відповіді.
Луціо

Відповіді:


177

Для отримання доступу до даних ReadableStreamвам потрібно зателефонувати в один із методів перетворення ( тут доступні документи ).

Як приклад:

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": "..." }
  });

РЕДАКТУВАННЯ: Якщо тип повернення даних не JSON або ви не хочете JSON, тоді використовуйтеtext()

Як приклад:

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

Сподіваюсь, це допомагає з’ясувати речі.


1
Дякуємо за відповідь. Я спробував це, і я все ще отримую ту ж помилку, коли res.body не визначено. Однак я можу отримати статус, але спочатку функцію () з res.status. Здається, що лише тіло є об'єктом ReadableStream. Здається, заблокована властивість, яка встановлена ​​в істину?
noob

Куди ви намагаєтесь отримати доступ res.body(це не є частиною мого прикладу)? Чи можете ви поділитися зразком коду в оригінальному запитанні, щоб зрозуміти, де може бути ваша проблема.
Ешлі 'CptLemming' Вілсон

1
Я спробував отримати доступ до res.body з відповіді json, яка була повернута в першій функції .then (). Для більшої ясності я додав зразок до свого початкового запитання. Дякую!
noob

1
Дивовижно, використовуючи реакцію та запит рідних, і цікаво, що у світі робити з ReadableStream, і це зробило трюк. ++
edencorbin

Просто голова, здається, ніби не сприймає, але переконайтесь, що бекенд, у який ви потрапляєте, насправді забезпечує дійсний JSON! Однозначно не кажучи з досвіду.
абеліто

44

Деякі люди можуть знайти asyncприклад корисним:

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

json()перетворює тіло відповіді з ReadableStreamоб'єкта в json.

Ці awaitзаяви повинні бути загорнуті в asyncфункції, однак ви можете запустити awaitзаяви безпосередньо в консолі Chrome (у версії 62).


1
Іноді справжня відповідь для вас насправді є №2 ха-ха, є сенс, чому вони зробили б .json () асинхронним, але це було не відразу очевидно
Sanchit Batra

29

res.json()повертає обіцянку. Спробуйте ...

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

3
Я спробував це, і він надрукував Обіцянку замість тіла.
reectrix

Спробуйте .thenfetch(...).then(res => res.json()).then(data => console.log(data))
Оскар Гомес

12

Трохи запізнювались на вечірку, але виникли деякі проблеми з отриманням чогось корисного з ReadableStreamотриманого з пакетного запиту Odata $ за допомогою Sharepoint Framework.

У мене були подібні проблеми, як у ОП, але в моєму випадку рішення було використовувати інший метод перетворення, ніж .json(). У моєму випадку .text()працював як шарм. Однак, для отримання якихось корисних JSON з текстового файлу було необхідне деяке хитання.


2
Дякую! Це працювало для мене. Я надсилаю ілюмінаційний http-відповідь з мого сервера Laravel простим return $data;. Нарешті я зміг прочитати цю відповідь у браузері зfetch(...).then(response => response.text()).then(data => console.log(data));
Камерон Хадсон,

10

Якщо ви просто хочете, щоб відповідь була текстовою, і ви не хочете конвертувати її в JSON, використовуйте https://developer.mozilla.org/en-US/docs/Web/API/Body/text, а потім, thenщоб отримати фактичну результат обіцянки:

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

або

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

2

Мені не подобається прикувати тени. Другий тоді не має доступу до статусу. Як було сказано раніше, 'response.json ()' повертає обіцянку. Повернення тодішнього результату 'response.json ()' у діях, подібних до секунди. Він має додатковий бонус за те, щоб бути в межах відповіді.

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

Ланцюг thenдопомагає отримати остаточне розв'язане значення (the body). Вклавши їх, ви не зможете отримати bodyзначення без зворотного дзвінка чи якогось подібного механізму. Уявіть собі , це: let body = await fetch(...).then(res => res.json()).then(data => data). Це не працюватиме вкладеним способом. Щоб перевірити, response.statusви завжди можете throwвиняток усередині першого thenта додати catchдо всього ланцюжка обіцянок.
Óscar Gómez

0

Зауважте, що ви можете прочитати потік лише один раз, тому в деяких випадках вам може знадобитися клонувати відповідь, щоб повторно його прочитати:

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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.