
Доброго времени суток, друзья!
При разработке веб-приложений часто возникает необходимость получения данных с сервера.
На сегодняшний день в JavaScript существует большое количество способов отправки HTTP-запросов.
В данной статье будут рассмотрены следующие приемы:
- XMLHttpRequest
- JQuery.ajax
- Qwest
- SuperAgent
- Http-client
- Axios
- Fetch
Рассмотрим синтаксис каждого вида на примере простых GET и POST-запросов. Остановимся на плюсах и минусах каждого способа.
В завершение реализуем парочку примеров с использованием XMLHttpRequest, Axios и Fetch.
XMLHttpRequest
Объект XMLHttpRequest — это старейший метод из рассматриваемых. Разумеется, другие методы превосходят его по функциональности. Однако он продолжает работать (в чем мы убедимся, когда перейдем к примерам) и может быть полезен для обеспечения обратной совместимости со старыми браузерами. Нельзя также забывать о его завершенности (чуть не написал «совершенстве»).
GET
let xhr = new XMLHttpRequest() xhr.open('GET', 'https://example.com/users') xhr.send() xhr.onload = function() { if (xhr.status != 200) { console.log(`error ${xhr.status}: ${xhr.statusText}`) } else { // работаем с данными console.log(xhr.response) } } xhr.onerror = function() { // обрабатываем ошибки }
POST
let formData = new FormData() formData.append('name', 'Harry') let xhr = new XMLHttpRequest(); xhr.open('POST', 'https://example.com/users'); xhr.send(formData); xhr.onload = () => console.log(xhr.response);
Преимущества:
- работает во всех браузерах
- является встроенным API браузера
- отсутствует необходимость загрузки из внешнего источника
- завершенность, стабильность
Недостатки:
- неуклюжий и многословный синтаксис
- может привести к «аду функций обратного вызова»
- заменяется на fetch при интерпретации
JQuery.ajax
Это широко используемая с давних пор библиотека для отправки асинхронных запросов.
Все методы ajax возвращают абстракцию (надстройку) над объектом XMLHttpRequest.
GET
$.ajax({ url: 'https://example.com/users' }).done(function(data) { // работаем с данными console.log(data) }).fail(function(error) { // обрабатываем ошибки console.log(error) })
POST
$.ajax({ method: "POST", url: "https://example.com/users", data: { name: 'Harry', age: 29 } }) .done(function(msg) { console.log( 'data saved: ' + msg ); })
Преимущества:
- хорошая поддержка и документация
- объект запроса можно настраивать
- используется во многих проектах
- прост в изучении
- имеется возможность прерывания запроса
Недостатки:
- не является встроенным API браузера
- необходимо загружать из внешнего источника
- приходится добавлять весь функционал JQuery
Qwest
Qwest — это простая ajax-библиотека, основанная на промисах и поддерживающая тип данных XmlHttpRequest2, похожий на ArrayBuffer, Blob и FormData.
GET
qwest.get('https://example.com/users') .then(function(xhr, response) { // работаем с данными console.log(response) });
POST
qwest.post('https://example.com/users', { name: 'Harry', age: 29 }) .then(function(xhr, response) { // работаем с данными console.log(response) }) .catch(function(e, xhr, response) { // обрабатываем ошибки console.log(e) })
Преимущества:
- можно устанавливать ограничения на количество запросов
- основан на промисах
Недостатки:
- XmlHttpRequest2 доступен не во всех браузерах
- не является встроенным
- необходимо загружать из внешнего источника
Superagent
Superagent (visionmedia) — это простой в изучении ajax API, созданный для повышения гибкости и читаемости кода. Он также работает с node.js.
GET
const superagent = require('superagent') superagent .get('https://example.com/users') .end((err, res) => { // работаем с данными console.log(res) })
Метод query() принимает объекты — строки запросов.
superagent.get('https://example.com/users') .query({ name: 'Harry' }) .query({ age: 29 }) .end(response => { console.log(response) })
POST
superagent.post('https://example.com/users') .send({ name: 'Harry' }) .set('Accept', 'application/json') .end(response => { console.log(response) })
Преимущества:
- основан на промисах
- работает как в браузере, так и в node.js
- для прерывания запроса вызывается метод request.abort()
- хорошо известная в сообществе разработчиков библиотека
- простой интерфейс
- поддержка повторных запросов
Недостатки:
- не поддерживается мониторинг процесса загрузки
- не является встроенным
- необходимо загружать из внешнего источника
Http-client
Http-client позволяет формировать клиент HTTP, используя Fetch API.
GET
// используем ES-6 модули import { createFetch, base, accept, parse } from 'http-client' const fetch = createFetch( base('https://example.com/users'), accept('application.json'), parse('json') ) fetch('https://example.com/users').then(response => { console.log(response.jsonData) })
POST
import { createFetch, method, params } from 'http-client' const fetch = createFetch( params({ name: 'Harry' }), base('htpps://example.com/users') )
Преимущества:
- работает как в браузере, так и в node.js
- используется сервис-воркерами
- основан на промисах
- обеспечивает хорошую защиту в политике общего происхождения
Недостатки:
- не является встроенным
- необходимо загружать из внешнего источника
Axios
Основанная на промисах библиотека для работы с запросами как в браузере, так и в node.js.
GET
const axios = require('axios'); axios.get('https://example.com/users') .then(function(response) { // работаем с данными console.log(response); }) .catch(function(error) { // обрабатываем ошибки console.log(error); })
POST
axios.post('/user', { name: 'Harry', age: 29 }) .then(function(response) { console.log(response); }) .catch(function(error) { console.log(error); })
Преимущества:
- использует промисы для решения проблемы «ада функций обратного вызова»
- работает как в браузере, так и в node.js
- поддерживается мониторинг процесса загрузки
- можно устанавливать задержку получения ответа
- имеется возможность настройки запросов
- реализована отмена промисов
- автоматическое преобразование данных в JSON
Недостатки:
- не является встроенным
- необходимо загружать из внешнего источника
Fetch
Fetch является встроенным API браузера, пришедшим на смену XMLHttpRequest. Он сильно упрощает работу с запросами. В основе fetch лежат промисы.
GET
fetch('https://example.com/users') .then(response => response.json()) .then(result => console.log(result)))
POST
fetch('https://example.com/users', { method: 'post', headers: { 'Accept': 'application/json' }, body: JSON.stringify({ name: 'Harry' }) }) .then(res => res.json()) .then(res => console.log(res))
Преимущества:
- является встроенным
- не требуется загружать из внешнего источника
- основан на промисах
- не нуждается в определении зависимостей
- поддерживается всеми современными браузерами
- официальная замена XMLHttpRequest
- низкий порог вхождения
Недостатки:
- двухэтапный процесс: сначала мы делаем запрос, затем вызываем метод .json(). В Axios мы получаем ответ в формате JSON по умолчанию
- промис, возвращаемый Fetch(), отклоняется только в случае возникновения каких-либо проблем с сетью. Если ответом сервера будет 404 или 500, промис все равно выполняется
- не хватает полезного функционала других библиотек, например, возможности отменять запросы
- fetch по умолчанию не отправляет и не получает куки с сервера, что может привести к квалификации запроса как неаутентифицированного и его блокировке. Одним из способов решения данной проблемы является добавление { credentials: ‘same-origin’ } в объект запроса
Примеры
Давайте посмотрим, как XMLHttpRequest, Fetch и Axios используются на практике. В задачах будет использоваться JSONPlaceholder — фейковый онлайн REST API для тестирования и прототипирования (проще говоря, учебная база данных).
XMLHttpRequest
Задача: получить список пользователей и вывести этот список в консоль.
Решение:
// создаем объект XMLHttpRequest с помощью конструктора let xhr = new XMLHttpRequest() // открываем соединение xhr.open('GET', 'https://jsonplaceholder.typicode.com/users') // отправляем запрос xhr.send() /*xhr.onload = function() { if (xhr.status != 200) { console.log(`error ${xhr.status}:${xhr.statusText}`) } else { console.table(JSON.parse(xhr.response)) } }*/ // сокращенный вариант // если запрос провалился, выводим в консоль статус // если выполнился, парсим ответ и выводим его в консоль xhr.onload = () => xhr.status != 200 ? console.error(xhr.status) : console.table(JSON.parse(xhr.response)) // мониторим процесс загрузки // если ответ содержит заголовок Content-Length, показываем процесс загрузки в байтах // если не содержит, показываем общее количество загруженных байт xhr.onprogress = event => { if (event.lengthComputable) { console.dir(`received ${event.loaded} of ${event.total} bytes`) } else { console.dir(`received ${event.loaded} bytes`) } } // обрабатываем другие ошибки xhr.onerror = () => console.error('error')
Результат:

Код на GitHub.
Fetch
Задача: аналогичная.
Решение (сравните с XMLHttpRequest):
fetch('https://jsonplaceholder.typicode.com/users') .then(response => response.json()) .then(json => console.table(json)) .catch(error => console.error(error))
Результат:

Код на GitHub.
Либо, если вам больше нравится async/await:
(async () => { try { const response = await fetch('https://jsonplaceholder.typicode.com/users') const data = await response.json() console.table(data) } catch (error) { console.error(error) } finally { console.log('done') } })()
Результат:

Код на GitHub.
Немного усложним задачу: теперь нужно получить с сервера изображения и сформировать из них галерею.
Решение:
const url = 'https://jsonplaceholder.typicode.com/photos/' getPhotosAndMakeGallery(url) function getPhotosAndMakeGallery(url) { for (let i = 1; i < 11; i++) { fetch(url + i) .then(response => response.json()) .then(photo => { let img = document.createElement('img') img.src = photo.url document.body.append(img) }) } }
Результат:

Код на GitHub.
Axios
Для подключения данной библиотеки необходимо добавить <script src=«unpkg.com/axios/dist/axios.min.js»></script> в head документа.
Задача: получить список пользователей и вывести их в консоль.
Решение:
axios.get('https://jsonplaceholder.typicode.com/users') .then(response => console.table(response.data)) .catch(error => console.log(error))
Код на GitHub.
Либо, если вы предпочитаете async/await:
(async () => { try { const response = await axios.get('https://jsonplaceholder.typicode.com/users'); console.table(response.data); } catch (error) { console.error(error); } })()
Код на GitHub.
Усложняем задачу: получить todos и сформировать список.
Решение:
const url = 'https://jsonplaceholder.typicode.com/todos/' getTodosAndMakeList() function getTodosAndMakeList() { const ul = document.createElement('ul') document.body.append(ul) for (let i = 1; i < 21; i++) { axios.get(url + i) .then(response => { let li = document.createElement('li') li.textContent = `title: ${response.data.title}; completed: ${response.data.completed}` ul.append(li) }) .catch(error => console.log(error)) } }
Результат:

Код на GitHub.
Еще усложняем: получить пользователей, комментарии и фото, объединить эти данные и представить все в удобочитаемом виде.
Решение:
function getUsers(i) { return axios.get('https://jsonplaceholder.typicode.com/users/' + i) } function getComments(i) { return axios.get('https://jsonplaceholder.typicode.com/comments/' + i) } function getPhotos(i) { return axios.get('https://jsonplaceholder.typicode.com/photos/' + i) } (async() => { for (let i = 1; i < 7; i++) { let request = await axios.all([getUsers(i), getComments(i), getPhotos(i)]) .then(axios.spread(function(user, comment, photo) { let figure = document.createElement('figure') document.body.append(figure) let figcaption = document.createElement('figcaption') figcaption.textContent = `Post ${i}` figure.append(figcaption) let img = document.createElement('img') img.src = photo.data.url figure.append(img) let userName = document.createElement('p') userName.innerHTML = `<span>Name:</span> ${user.data.username}` figure.append(userName) let userComment = document.createElement('p') userComment.innerHTML = `<span>Comment:</span> ${comment.data.body}` figure.append(userComment) })) } })()
Результат:

Код на GitHub.
Благодарю за внимание.
Счастливого кодинга!
ссылка на оригинал статьи https://habr.com/ru/post/493206/
Добавить комментарий