XMLHttpRequest: обзор (устаревший)
XMLHttpRequest (XHR) — браузерный API для асинхронных HTTP-запросов, предшественник Fetch API, основа AJAX-эпохи (2005–2015).
Зачем нужно
XHR встречается в легаси-коде и старых библиотеках (jQuery $.ajax, Axios в старых версиях). Понимание XHR необходимо для чтения и поддержки кода, написанного до 2015 года, а также для понимания эволюции браузерных API. Для нового кода используйте Fetch API.
Где используется
- Легаси-код, написанный до 2015–2017 годов
- Старые версии jQuery, Axios (теперь использует fetch/http)
- Прогресс загрузки файлов — XHR.onprogress (fetch не поддерживает нативно)
- IE11 и очень старые браузеры (fetch там недоступен)
XHR vs Fetch
| Критерий | XMLHttpRequest | Fetch |
|---|---|---|
| API | callback-based | Promise-based |
| Прогресс | xhr.onprogress |
нет нативно |
| Отмена | xhr.abort() |
AbortController |
| CORS | поддерживается | поддерживается |
| Читаемость | низкая | высокая |
| IE11 | да | нет (нужен polyfill) |
Базовый пример XHR
// GET-запрос
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api/users');
xhr.setRequestHeader('Authorization', `Bearer ${token}`);
xhr.onload = function {
if (xhr.status === 200) {
const users = JSON.parse(xhr.responseText);
console.log(users);
} else {
console.error('Ошибка:', xhr.status, xhr.statusText);
}
};
xhr.onerror = function {
console.error('Сетевая ошибка');
};
xhr.send;
// POST-запрос с JSON
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/users');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = () => {
if (xhr.status === 201) {
const created = JSON.parse(xhr.responseText);
console.log('Создан:', created.id);
}
};
xhr.send(JSON.stringify({ name: 'Антон', email: 'anton@example.com' }));
Прогресс загрузки (уникальная возможность XHR)
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/upload');
// Прогресс отправки файла
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
const percent = (event.loaded / event.total * 100).toFixed(1);
progressBar.style.width = percent + '%';
console.log(`Загружено: ${percent}%`);
}
};
xhr.onload = () => console.log('Загрузка завершена:', xhr.status);
const formData = new FormData();
formData.append('file', fileInput.files[0]);
xhr.send(formData);
Эквивалент на Fetch (современный код)
// XHR выше переписывается на Fetch так:
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Антон', email: 'anton@example.com' }),
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const created = await res.json();
console.log('Создан:', created.id);
Частые ошибки
- Использование XHR в новом коде — есть Fetch API, значительно удобнее
- Забывают вызвать
xhr.send— запрос не отправляется - Проверяют
xhr.statusвxhr.onerror— там status всегда 0 (сетевая ошибка) - Не устанавливают
Content-Typeпри отправке JSON — сервер не знает формат
Связанные темы
- _MOC Сеть
- _MOC JavaScript
- Fetch -- headers, mode, credentials
- Abort Controller -- отмена запросов
- Протокол HTTP -- основы