Рассмотрим взаимодействие с сервером при помощи асинхронных запросов на чистом JavaScript, без сторонних библиотек. Используем два способа: XMLHttpRequest (XHR) и Fetch API.
Использование сервиса JSON Placeholder
Для отправки запросов используем сервис JSON Placeholder — фейковый онлайн REST API для тестирования и прототипирования. Он предоставляет различные примеры ресурсов, включая ресурс users, возвращающий JSON-массив пользователей. Его URL используется в запросах.
XMLHttpRequest (XHR)
XHR — аббревиатура от XMLHTTPRequest. Создадим объект при помощи конструктора глобального класса XMLHttpRequest:
let xhr = new XMLHttpRequest();
Отправим запрос методом open(). Первый параметр — метод запроса (GET, POST, PUT, PATCH, DELETE), второй — URL. Используем GET-запрос для получения данных с /users:
xhr.open('GET', 'https://jsonplaceholder.typicode.com/users');
После open() отправим запрос методом send():
xhr.send();
Для проверки запроса воспользуйтесь вкладкой Network в DevTools браузера. Она отображает все сетевые запросы, включая XHR-запросы, с возможностью фильтрации по типу, методу и другим параметрам. Вкладка содержит информацию о заголовках запроса (Request Headers), ответе сервера (Response Headers), самом ответе (Response) и других данных.
Обработка ответа и ошибок
Ответ сервера — строка. Для работы с ней как с JavaScript-объектом используем JSON.parse(). Обработка ответа и ошибок осуществляется обработчиками событий onload и onerror:
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 400) {
console.log('Успешный ответ:', JSON.parse(xhr.responseText));
} else {
console.error('Ошибка:', xhr.status);
}
};
xhr.onerror = function() {
console.error('Ошибка запроса');
};
xhr.responseText содержит строку, JSON.parse() преобразует её в объект. onload проверяет статус ответа (200-399 — успешный ответ). onerror вызывается при ошибке запроса (например, отсутствии соединения). Для более детальной обработки ошибок можно использовать xhr.status и xhr.statusText.
Метод POST
Для отправки POST-запросов добавим тело запроса (body) и укажем заголовок Content-Type:
let data = { name: 'Vladilen', age: 26 };
xhr.open('POST', 'https://jsonplaceholder.typicode.com/users');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(data));
Обратите внимание на JSON.stringify() для преобразования объекта data в JSON-строку.
Универсальная функция с Promise
Для улучшения читаемости и удобства работы с асинхронным кодом создадим универсальную функцию sendRequest(), использующую Promise:
function sendRequest(method, url, body = null) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.responseType = 'json'; // Ожидаем JSON-ответ
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 400) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
};
xhr.onerror = () => {
reject(new Error('Ошибка запроса'));
};
xhr.setRequestHeader('Content-Type', 'application/json'); // Заголовок для POST-запросов
xhr.send(body); // Отправляем тело запроса, если оно есть
});
}
Функция принимает метод, URL и необязательное тело запроса. Она возвращает Promise, разрешающийся успешным ответом или отклоняющийся ошибкой.
Fetch API
Fetch API — более современный способ работы с асинхронными запросами, также возвращающий Promise:
function sendRequest(method, url, body = null) {
const headers = { 'Content-Type': 'application/json' }; // Заголовки
return fetch(url, {
method,
headers,
body: body ? JSON.stringify(body) : null // Тело запроса
}).then(response => {
if (!response.ok) {
throw new Error(`Ошибка HTTP: ${response.status}`); // Выбрасываем ошибку при неуспешном ответе
}
return response.json(); // Возвращаем Promise с парсингом JSON-ответа
});
}
Функция аналогична предыдущей, но использует fetch. Обратите внимание на обработку ошибок с помощью response.ok и выброс исключения.
Рассмотрены два способа отправки асинхронных запросов на сервер: XMLHttpRequest и Fetch API. Fetch API более современный и удобный, но XHR остаётся универсальным и поддерживается всеми браузерами. Выбор метода зависит от требований проекта и предпочтений разработчика. Важно понимать принципы клиент-серверного взаимодействия и уметь обрабатывать ответы и ошибки.