JS: DOM API

AJAX

Манипуляции с DOM деревом помогают сделать наши сайты более живыми, но их всё же недостаточно для создания автономных виджетов или полноценных (имеющих бекенд) Single Page Application (SPA).

Рассмотрим конкретный пример. Многие сервисы дают возможность использовать разные виджеты, например, погода или курсы валют. Работает это так: вы вставляете в свой html код, предоставленный сервисом. Далее этот код подгружает сам виджет и периодически обращается за необходимыми данными на сервера сервиса. Это может происходить в тот момент, когда пользователь виджета нажимает кнопки, требующие новых данных: например, показать погоду на следующую неделю.

Подобный виджет используется и на Хекслете: вы можете видеть его в правом нижнем углу на каждой странице. В нем есть поиск по нашей справке и форма для отправки письма в поддержку. Виджет работает с помощью специального сервиса и никак не взаимодействует с бекендом Хекслета.

Ключевая технология в этой истории — механизм для выполнения http-запросов прямо из браузера. Именно его называют AJAX, что расшифровывается как "Asynchronous JavaScript and XML". Несмотря на название, эта технология работает не только с xml.

XMLHttpRequest

До появления html5, браузеры предоставляли (и сейчас предоставляют) специальный объект XMLHttpRequest:

const request = new XMLHttpRequest();
request.onreadystatechange = () => {
  if (request.readyState == 4 && request.status == 200) {
    document.getElementById('demo').innerHTML = request.responseText;
  }
};
request.open('GET', '/api/v1/articles/152.json', true);
request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
request.send();

Работать с ним крайне неудобно и, по сути, все использовали обертку, созданную в рамках библиотеки JQuery. Подробнее об этом будет в уроке, посвященному JQuery.

Fetch

С появлением стандарта HTML5, появился новый механизм для http запросов:

// const promise = fetch(url[, options]);
fetch('/api/v1/articles/152.json')
  .then((response) => {
    console.log(response.status); // => 200
    console.log(response.headers.get('Content-Type'));
    return response.json();
   })
  .then((article) => {
    console.log(article.title); // => 'Как использовать fetch?'
  })
  .catch(console.error);

Как видно, fetch — это функция, возвращающая промис, а значит работать с ней удобно и приятно. А благодаря наличию полифиллов, можно не переживать, что какой-то браузер не поддерживает этот механизм.

Обратите внимание на то, что response.json тоже возвращает промис. Кроме json данные можно получать, используя функции blob, text, formData и arrayBuffer.

Отправка формы POST запросом:

const form = document.querySelector('form');

fetch('/users', {
  method: 'POST',
  body: new FormData(form),
});

Отправка формы как json:

fetch('/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Hubot',
    login: 'hubot',
  })
})

При всех своих преимуществах fetch довольно низкоуровневый механизм. Например, работая с json (очень частый вариант), придется самостоятельно выставлять заголовки и делать разные манипуляции с данными, которые можно было бы автоматизировать.

На практике, это привело к созданию различных библиотек, которые работают схожим образом, но дают гораздо больше возможностей. Причем многие из этих библиотек изоморфные, то есть работают одинаково и в браузере, и на сервере. Одна из самых популярных библиотек на момент создания курса - axios.

URL

Как мы знаем из предыдущих курсов, клеить строчки для работы с путями или урлами это плохая идея. Можно легко ошибиться и, в целом, приходится выполнять работу, которую может выполнять машина. В Node.js с этим никаких проблем, у нас есть соответствующие модули, а вот в браузере это всегда вызывало сложности. Распарсить или собрать url легко и просто не получалось.

С одной стороны, можно всегда воспользоваться сторонними библиотеками, которых достаточно много, но с другой, в браузерах уже есть встроенный для этого механизм (обычно добавляется полифиллами).

const url = new URL('../cats', 'http://www.example.com/dogs');
console.log(url.hostname); // => www.example.com
console.log(url.pathname); // => /cats

url.hash = 'tabby';
console.log(url.href); // => http://www.example.com/cats#tabby

url.pathname = 'démonstration.html';
console.log(url.href); // => http://www.example.com/d%C3%A9monstration.html

Что особенно приятно, fetch умеет работать с объектом URL напрямую:

const response = await fetch(new URL('http://www.example.com/démonstration.html'));

А вот как можно работать с query параметрами:

// https://some.site/?id=123
const parsedUrl = new URL(window.location.href);
console.log(parsedUrl.searchParams.get('id')); // => 123
parsedUrl.searchParams.append('key', 'value')
console.log(parsedUrl); // => https://some.site/?id=123&key=value

HTTP access control (CORS)

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

Подробно об этом механизме можно прочитать тут


<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

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

Получить доступ
115
курсов
892
упражнения
2241
час теории
3196
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 115 курсов, 2000+ часов теории
  • 800 практических заданий в браузере
  • 250 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».