О том, как сделать запрос на сервер

от автора

… и получить ответ, разумеется.

Доброго времени суток, друзья!

При разработке веб-приложений часто возникает необходимость получения данных с сервера.

На сегодняшний день в 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *