~ 8 мин
Как получать тело ответа с помощью fetch в JavaScript
376
3/31/2024
FetchAPI специально разработано для удобства получения данных и поддерживает множество различных форматов данных, включая JSON, XML и бинарные данные. Он предоставляет простой синтаксис на основе промисов для выполнения HTTP-запросов и может использоваться как в браузере, так и в среде Node.js.
FetchAPI специально разработано для удобства получения данных и поддерживает множество различных форматов данных, включая JSON, XML и бинарные данные. Он предоставляет простой синтаксис на основе промисов для выполнения HTTP-запросов и может использоваться как в браузере, так и в среде Node.js.
Для справки
При использовании метода fetch() для отправки запроса на сервер, вы получите обратно промис, который после того, как выполнится вернет объект Response. Объект Response представляет собой полный HTTP-ответ, включая статус, заголовки и тело. Однако тело не доступно непосредственно как строка или объект, а скорее как поток данных, который можно прочитать только один раз.
Для обработки тела ответа нужно будет использовать один из методов объекта Response, который возвращает другой промис, результатом выполнения которого станут спарсенные данные. Объект Response может возвращать следующие методы:
.json(): Возвращает промис, в результате выполнения которого возвращается JSON.
.text(): Возвращает промис, в результате выполнения которого возвращается строка.
.blob(): Возвращает промис, в результате которого возвращается Blob. Blob представляет собой подобие объекта файла неизменяемых, необработанных данных.
.arrayBuffer(): Возвращает промис, который возвращает ArrayBuffer, и представляет собой общий, фиксированной длины буфер двоичных данных.
.formData(): Возвращает промис, который возвращает FormData в виде структуры данных пары ключ-значение, используемой для отправки данных формы.
Когда использовать .json()
Несмотря на то, что метод называется .json(), результатом не является сам JSON, а ответ является результатом преобразования JSON в объект JavaScript. Этот объект может быть чем угодно, что может быть представлено в формате JSON — объектом, массивом, строкой, числом и т. д.
Используйте этот метод, когда вы хотите получить тело ответа в виде объекта JavaScript, разобранного из текста JSON. Это полезно для работы с данными, следующими формату JSON, такими как большинство API. Например, вы можете использовать этот метод, чтобы получить информацию о пользователе из API GitHub или данные о погоде из API погоды.
Вот пример, как сделать запрос к API Reddit и отобразить заголовки лучших постов на главной странице, используя метод .json():
async function getRedditPosts() { try { const response = await fetch('https://www.reddit.com/r/all/top.json?limit=10'); const data = await response.json(); const posts = data.data.children.map(child => child.data); console.log(posts.map(post => post.title)); } catch (error) { console.error(error); } } // С использование синтаксиса промисов: function getRedditPosts() { fetch('https://www.reddit.com/r/all/top.json?limit=10') .then(response => response.json()) .then(data => { const posts = data.data.children.map(child => child.data); console.log(posts.map(post => post.title)); }) .catch(error => console.error(error)); }
Когда использовать .text()
Используйте этот метод, когда вы хотите получить тело ответа в виде обычной текстовой строки, независимо от типа контента. Это полезно для целей отладки или когда вам нужно обработать текст самостоятельно. Например, вы можете использовать этот метод, чтобы получить исходный код HTML веб-страницы или данные XML ленты RSS.
Вот пример как сделать запрос к API GitHub и отобразить содержимого файла с использованием метода .text():
async function displayFileContentsAsync() { try { const response = await fetch('https://api.github.com/repos/github/gitignore/contents/Node.gitignore'); const text = await response.text(); console.log(text); } catch (error) { console.error(error); } } // С использование синтаксиса промисов: function displayFileContentsPromise() { fetch('https://api.github.com/repos/github/gitignore/contents/Node.gitignore') .then(response => response.text()) .then(text => console.log(text)) .catch(error => console.error(error)); }
Когда использовать .blob()
Используйте этот метод, когда вы хотите получить тело ответа в виде объекта Blob, содержащего двоичные данные. Это полезно для работы с данными, которые не являются текстовыми, такими как изображения, видео, аудио или файлы PDF. Например, вы можете использовать этот метод, чтобы получить изображение из API изображений или файл PDF из API документов.
Вот пример как сделать запрос к файлу изображения на сервере с использованием метода .blob():
async function displayImageAsync() { try { const response = await fetch('https://www.example.com/image.jpg'); const blob = await response.blob(); const url = URL.createObjectURL(blob); const img = document.createElement('img'); img.src = url; document.body.appendChild(img); } catch (error) { console.error(error); } } // С использование синтаксиса промисов: function displayImagePromise() { fetch('https://www.example.com/image.jpg') .then(response => response.blob()) .then(blob => { const url = URL.createObjectURL(blob); const img = document.createElement('img'); img.src = url; document.body.appendChild(img); }) .catch(error => console.error(error)); }
Когда использовать .arrayBuffer()
Используйте этот метод, когда вы хотите получить тело ответа в виде объекта ArrayBuffer, содержащего необработанные байты. Это полезно для работы с данными, которые требуют манипулирования на низком уровне, такими как шифрование, сжатие или декодирование. Например, вы можете использовать этот метод, чтобы получить ZIP-файл из API файлов или WAV-файл из API аудио.
Вот пример сделать запрос к аудиофайлу на сервере с использованием метода .arrayBuffer():
async function playAudioAsync() { try { const response = await fetch('https://www.example.com/audio.mp3'); const arrayBuffer = await response.arrayBuffer(); const audioBuffer = await new AudioContext().decodeAudioData(arrayBuffer); const source = new AudioBufferSourceNode(new AudioContext(), { buffer: audioBuffer }); source.connect(new AudioContext().destination); source.start(0); } catch (error) { console.error(error); } } // С использование синтаксиса промисов: function playAudioPromise() { fetch('https://www.example.com/audio.mp3') .then(response => response.arrayBuffer()) .then(arrayBuffer => new AudioContext().decodeAudioData(arrayBuffer)) .then(audioBuffer => { const source = new AudioBufferSourceNode(new AudioContext(), { buffer: audioBuffer }); source.connect(new AudioContext().destination); source.start(0); }) .catch(error => console.error(error)); }
Когда использовать .formData()
Используйте этот метод, когда вы хотите получить тело ответа в виде объекта FormData, содержащего данные формы. Это полезно для работы с данными, которые отправляются с использованием HTML-форм, таких как multipart/form-data или application/x-www-form-urlencoded. Например, вы можете использовать этот метод, чтобы получить ввод пользователя из формы обратной связи или формы загрузки файла.
Этот метод редко используется, потому что большинство API не возвращают данные формы в качестве ответа, а возвращают данные JSON или XML. Кроме того, объекты FormData не так легко проверить или изменить, так как в них нет встроенного способа перебора их элементов или преобразования их в другие форматы.
Тем не менее, он особенно полезен в контексте служебных программ из-за их возможности перехватывать сетевые запросы и манипулировать их данными.
Служебные программы - это сценарии, которые запускаются в фоновом режиме веб-приложения и могут перехватывать и обрабатывать сетевые запросы. Используя метод .formData(), вы можете перехватить запрос на отправку формы, изменить данные формы, а затем отправить измененные данные формы на сервер. Это может быть полезно для различных целей, таких как регистрация данных формы, добавление дополнительных полей к данным формы или фильтрация конфиденциальных данных.
Вот пример служебной программы, перехватывающей запрос на отправку формы и изменяющей данные формы с использованием метода .formData():
self.addEventListener('fetch', event => { // Intercept form submission requests if (event.request.method === 'POST' && event.request.headers.get('Content-Type') === 'application/x-www-form-urlencoded') { event.respondWith(handleFormSubmission(event.request)); } }); async function handleFormSubmission(request) { // Parse the form data from the request body const formData = await request.formData(); // Modify the form data formData.append('extra-field', 'extra-value'); // Create a new request with the modified form data const newRequest = new Request(request.url, { method: request.method, headers: request.headers, body: new URLSearchParams(formData) }); // Make the modified request to the server return fetch(newRequest); }
Загрузка изображений в формате Base64
В Node.js нет встроенного FileReader, так как он предназначен для использования в браузерах. В Node.js для работы с файлами и буферами используют Buffer, fs (файловая система), и stream, которые предоставляют функциональность, аналогичную FileReader для серверной стороны.
Вместо FileReader, можно использовать Buffer для чтения данных и преобразования их в base64, как в примере ниже. Buffer позволяет легко работать с бинарными данными в Node.js, и он может выполнять все, что делал бы FileReader для работы с бинарными файлами.
const imageUrl = "https://images.pexels.com/photos/15894618/pexels-photo-15894618.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1" async function start() { const response = await fetch(imageUrl) const arrayBuffer = await response.arrayBuffer() const base64data = Buffer.from(arrayBuffer).toString("base64") const dataUrl = `data:${response.headers.get("content-type")};base64,${base64data}` console.log(JSON.stringify(dataUrl, null, 2)) } start()
Взгляните на наш стартап:
Выбирай экскурсии и активности по всему миру
Уже зарегистрировано 0 стран, 0 направлений, 0 экскурсий
Есть интересная идея?
И вы очень хотите ее реализовать, пишите нам и получите подробное коммерческое предложение и быструю реализацию