# Получаем данные в Javascript с помощью XMLHttpRequest

poster
В этом видео мы с вами разберем, как получать в Javascript данные от сервера с помощью HTTP запросов.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Я очень часто вижу, что люди используют $http в Angular или jQuery или другие библиотеки и даже не знают, что выполняется внутри и как в чистом javascript работать с http запросами.

Поэтому в этом видео мы с вами разберем, как получать в javascript данные от сервера. То есть идея в том, чтобы получить данные от сервера асинхронно с помощью HTTP-запроса и изменить страницу у пользователя без перезагрузки.

Именно на этой технологии работают все современные Single Page приложения.

Для этого используется XMLHttpRequest. Из его названия можно подумать, что он может работать только с xml, но это не так. Он может работать с любыми данными.

Для того, чтобы обращатся на сервер за данными, давайте создадим API с тестовыми данными с помощью сервиса mocky.io.

Вот у меня есть JSON данных

[
  {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },
  {
    "userId": 1,
    "id": 2,
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  },
  {
    "userId": 1,
    "id": 3,
    "title": "ea molestias quasi exercitationem repellat qui ipsa sit aut",
    "body": "et iusto sed quo iure\nvoluptatem occaecati omnis eligendi aut ad\nvoluptatem doloribus vel accusantium quis pariatur\nmolestiae porro eius odio et labore et velit aut"
  }
]

Вставляем его в body запроса и в advance mode выбираем

 Access-Control-Allow-Origin:*

Для того, чтобы любой домен мог обращатся к этому API.

Нажимаем Generate response и получаем ссылку на наш API.

Теперь давайте писать javascript.

Для начала нам нужно создать новый екземпляр XMLHttpRequest.

var xhr = new XMLHttpRequest()

Теперь сконфигурировать какой url мы хотим получить

var xhr = new XMLHttpRequest()
xhr.open(
  'GET',
  'http://www.mocky.io/v2/5944e07213000038025b6f30',
  true
)

Для этого на xhr мы вызываем метод open передавая туда тип запроса, url, и асинхронный ли запрос. Конечно мы хотим асинхронный. Никогда не используйте синхронные запросы, так как это блокирует продолжение скрипта. В 99 случаях из 100 этого делать не нужно.

Не стоит думать, что xhr.open выполняет запрос. Хотя из названия похоже. Он его только конфигурирует. Для отправки запроса используется xhr.send

var xhr = new XMLHttpRequest()
xhr.open(
  'GET',
  'http://www.mocky.io/v2/5944e07213000038025b6f30',
  true
)
xhr.send()

Наш запрос отправлен, но мы никак не обработали получение данных. В этом нам поможет специальный метод onreadystatechange

var xhr = new XMLHttpRequest()
xhr.open(
  'GET',
  'http://www.mocky.io/v2/5944e07213000038025b6f30',
  true
)
xhr.send()

xhr.onreadystatechange = function() {
  if (xhr.readyState != 4) {
    return
  }
  console.log('end')
}

Внутри метода мы должны проверять readyState на 4, чтобы понять, когда запрос закончится. Пока readyState ниже четверки, то запрос не закончен. Там происходит начало запроса, получение заголовкой, загрузка body и только потом запрос завершен.

Теперь давайте добавим проверку на error и вывод результатов в консоль

var xhr = new XMLHttpRequest()
xhr.open(
  'GET',
  'http://www.mocky.io/v2/5944e07213000038025b6f30',
  true
)
xhr.send()

xhr.onreadystatechange = function() {
  if (xhr.readyState != 4) {
    return
  }

  if (xhr.status === 200) {
    console.log('result', xhr.responseText)
  } else {
    console.log('err', xhr.responseText)
  }
}

Как мы видим, результат выводится в виде строки, поэтому нам нужно еще и парсить его в JSON

console.log('result', JSON.parse(xhr.responseText))

Какие же основные минусы XMLHttpRequest и почему все используют ajax в jQuery для получения данных или отдельные библиотеки для этого например superagent или axios.

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

Второй - это отсутствие промисов при работе с XMLHttpRequest. Мы не можем написать .then, передать туда коллбек и выполнить что мы хотим когда запрос завершится. Поэтому с этим кодом неудобно работать.

Третий - это кроссбраузерность. Даже в IE 10-11 XMLHttpRequest работает не так, как в других браузерах.

Тем не менее понимать и помнить, что выполняется внутри нужно, хотя вряд ли вы будете его использовать в чистом виде.

Если у вас возникли какие-то вопросы или комментарии, пишите их прямо под этим видео.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Владимир
7 лет назад
Здравствуйте. Очень помогла Ваша статья и видео. Всё получилось, однако мне нужно многоразовое получение статуса. Я загнал всё внутрь новой функции и resultубрал из кода, При этом появилась ошибка о том, xhr.ststus не определён как объект Прошу Вашей помощи.function ready(){ var xhr = new XMLHttpRequest() xhr.open( 'GET', 'https://luckygames.io ', true ) xhr.send() xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return } if (xhr.status === 200) { console.log('Ok !', xhr.responseText ) // console.log('result', xhr.responseText) } else { console.log('err', xhr.responseText) } } }
Виталий Уряшник
8 лет назад
Подскажите пожалуйста почему этот код сразу запускается? xhr.onreadystatechange = function() { if (xhr.readyState != 4) { return } console.log('end') } Ведь не было запуска самого метода xhr.onreadystatechange()
monsterlessons
8 лет назад
Идея onreadystatechange, как и многих других нативных функций заключается в том, что мы переопределям определенную функцию своей, и потом xhr сам вызывает эту функцию в определенный момент. Это очень удобно, когда мы хотим расширить обьект определенной логикой
Alexey Sergeevich
8 лет назад
Спасибо, очень помогло
monsterlessons
8 лет назад
На здоровье)
evanre
8 лет назад
Привет, спасибо за ваши уроки. У меня все получилось, за исключением одного момента, может кому будет полезно. Я так и не смог получить 200й ответ от сервиса с локально открытого файла (file:///Users/evanre/learn/monster/XMLHttpRequest/index.html). В консоли постоянно выбивало 403 ошибку и жаловалось на отсутствие того самого хедера в запросе (Failed to load http://www.mocky.io/v2/5944e07213000038025b6f30: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.). После запуска локального сервера на Browser-Sync все пошло как по маслу)
monsterlessons
8 лет назад
Привет. На здоровье. Исходя из ошибки ему не хватает хедера Access-Control-Allow-Origin: *. Вы его точно ставили в mocky.io? Главное что получилось.
evanre
8 лет назад
Да, подключал я этот хедер, не знаю в чем была проблема, но на локальном сервере все работает.
Karen Kostanyan
9 лет назад
Я всегда использую XMLHttpRequest.... те минусы о котором говорилось свободно можно и избежать вот функция с колбеком function requestGet(url,callback){ var oAjaxReq = new XMLHttpRequest(); oAjaxReq.open("get", url, true); oAjaxReq.withCredentials = true; oAjaxReq.send(); oAjaxReq.onreadystatechange = callback; } а для кросса можно просто писать если не XMLHttpRequest то XDomainRequest и все но я рекомендую так не делать потому что те кто работают на IE и думают что это браузер пусть у них не работает не чего страшного например gmail в IE не работает ))))) но у каждого есть gmail ))))) так что XMLHttpRequest это самый правильный выбор ....
monsterlessons
9 лет назад
Спасибо за отзыв. Я писал из своего опыта больше. Если вас полностью устраивает XMLHttpRequest и покрывает ваши нужды то почему нет. Так как я чаще всего пишу изоморфные приложения, то предпочитаю использовать superagent. https://github.com/visionmedia/superagent Его можно использовать и на клиенте и в nodejs. Он работает начиная с IE7. Код выглядит как то так. const {body} = await superagent.get('http://google.com/api') Соответственно в body будет респонз уже приведенный в JSON.
Karen Kostanyan
9 лет назад
да интересная штука.... просто у я люблю все нативное ... думаю он бистре работает по любому