Манипуляции с DOM деревом помогают сделать наши сайты более живыми, но их всё же недостаточно для создания автономных виджетов или полноценных (имеющих бекенд) Single Page Application (SPA).
Рассмотрим конкретный пример. Многие сервисы дают возможность использовать разные виджеты, например, погода или курсы валют. Работает это так: вы вставляете в свой html код, предоставленный сервисом. Далее этот код подгружает сам виджет и периодически обращается за необходимыми данными на сервера сервиса. Это может происходить в тот момент, когда пользователь виджета нажимает кнопки, требующие новых данных: например, показать погоду на следующую неделю.
Подобный виджет используется и на Хекслете: вы можете видеть его в правом нижнем углу на каждой странице. В нем есть поиск по нашей справке и форма для отправки письма в поддержку. Виджет работает с помощью специального сервиса и никак не взаимодействует с бекендом Хекслета.
Ключевая технология в этой истории — механизм для выполнения http-запросов прямо из браузера. Именно его называют AJAX, что расшифровывается как "Asynchronous JavaScript and XML". Несмотря на название, эта технология работает не только с xml.
До появления 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.
С появлением стандарта 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.
Как мы знаем из предыдущих курсов, клеить строчки для работы с путями или урлами это плохая идея. Можно легко ошибиться и, в целом, приходится выполнять работу, которую может выполнять машина. В 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 запросы на клиенте могут использоваться злоумышленниками для кражи данных. Поэтому браузеры контролируют то, куда и как делаются запросы.
Подробно об этом механизме можно прочитать тут
Вам ответят команда поддержки Хекслета или другие студенты.
Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.
Загляните в раздел «Обсуждение»:
Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.
Наши выпускники работают в компаниях:
Зарегистрируйтесь или войдите в свой аккаунт