Основные варианты получения данных в веб-разработке на JS
Основные методы получения данных в JavaScript
В веб-разработке часто требуется извлечь информацию из внешних источников или из DOM. Рассмотрим несколько подходов. Самым современным и удобным считается fetch API. Он позволяет асинхронно выполнять HTTP-запросы и обрабатывать ответы.
Как получить данные с сервера, используя fetch?
Метод fetch возвращает Promise, который разрешается в объект Response. Для извлечения тела ответа применяются методы .json(), .text() и другие.
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Ошибка HTTP: ' + response.status);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Ошибка:', error));Js получить (получение данных в javascript)
В примере выполняется GET-запрос. Если статус ответа не в диапазоне 200-299, генерируется ошибка. Полученные данные преобразуются в JSON и выводятся в консоль. Блок catch отлавливает любые сетевые проблемы.
Типичные ошибки:
- Забыли проверить response.ok – при 404 или 500 fetch не считает это ошибкой и не переходит в catch.
- CORS-ограничения – запрос на другой домен может быть заблокирован без соответствующих заголовков сервера.
- Неправильный формат данных – если сервер вернул не JSON, вызов .json() вызовет исключение.
Цель: загрузка данных с API для отображения на странице или дальнейшей обработки. Этот подход применяется в большинстве современных проектов.
Каким образом выполнялись запросы до появления fetch? (XMLHttpRequest)
Объект XMLHttpRequest (XHR) позволяет отправлять HTTP-запросы. Несмотря на устаревание, он всё ещё используется в старых проектах или для отслеживания прогресса загрузки.
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
const data = JSON.parse(xhr.responseText);
console.log(data);
} else {
console.error('Ошибка: ' + xhr.status);
}
};
xhr.onerror = function() {
console.error('Сетевая ошибка');
};
xhr.send();
После open() нужно вызвать send(). События onload и onerror обрабатывают ответ. Ответ приходит в виде строки в responseText.
Проблемы:
- Код более громоздкий по сравнению с fetch.
- Необходимость вручную парсить JSON.
- Для отслеживания прогресса (загрузка файлов) требуется подписка на событие progress.
Цель: поддержка старых браузеров или специфические сценарии (например, загрузка файлов с индикатором прогресса).
Как извлечь значения из элементов формы?
Для получения данных из полей ввода, select, textarea используются свойства value, checked (для checkbox/radio) или API FormData.
const input = document.getElementById('name');
const value = input.value;
console.log('Имя:', value);
// Для select
const selected = document.querySelector('select').value;
// Для чекбокса
const isChecked = document.querySelector('input[type="checkbox"]').checked;
Простой способ, но при большом количестве полей становится неудобным. Лучше применять FormData.
Ошибки:
- Забыли обработать случай, когда элемент не найден (null).
- Для textarea тоже используется .value.
Цель: получение данных из формы для валидации или отправки.
Как получить данные из localStorage или sessionStorage?
Хранилище браузера позволяет сохранять пары ключ-значение. Извлечение выполняется методом getItem.
const savedData = localStorage.getItem('userSettings');
if (savedData) {
const settings = JSON.parse(savedData);
console.log(settings);
} else {
console.log('Данные не найдены');
}
Данные сохраняются в виде строк, поэтому сложные объекты нужно предварительно сериализовать через JSON.stringify, а при чтении – парсить.
Проблемы:
- Нельзя хранить большие объёмы (ограничение ~5 МБ).
- Устаревшие данные могут остаться после обновления приложения.
- Синхронный доступ – блокирует основной поток при чтении.
Цель: сохранение настроек пользователя, кэширование данных между сессиями.
Как собрать данные формы в структурированном виде без ручного перебора? (FormData)
Конструктор FormData принимает элемент form и автоматически собирает все поля.
const form = document.getElementById('myForm');
const formData = new FormData(form);
// Получить конкретное значение
const name = formData.get('username');
console.log(name);
// Перебор всех полей
for (let [key, value] of formData.entries()) {
console.log(key, value);
}
FormData поддерживает файлы, множественный выбор (multiple select) и группировку checkbox по имени.
Нюансы:
- Не включает кнопки отправки (submit).
- Если элемент не имеет атрибута name, он игнорируется.
- Для отправки через fetch можно передать formData напрямую в body.
Цель: удобный сбор данных формы для отправки на сервер или валидации.
Расширенные примеры получения данных
Ниже приведены нестандартные сценарии с подробным кодом и результатами.
Параллельная загрузка нескольких ресурсов с Promise.all
const urls = [
'https://jsonplaceholder.typicode.com/posts/1',
'https://jsonplaceholder.typicode.com/posts/2'
];
Promise.all(urls.map(url => fetch(url).then(res => res.json())))
.then(results => {
console.log('Получено два поста:');
results.forEach((post, i) => console.log(`Пост ${i+1}:`, post));
})
.catch(err => console.error('Ошибка при загрузке:', err));
Получено два поста:
Пост 1: {userId: 1, id: 1, title: "...", body: "..."}
Пост 2: {userId: 1, id: 2, title: "...", body: "..."}
Этот подход позволяет дождаться завершения всех запросов и получить массив результатов. Если хотя бы один запрос упадёт, Promise.all перейдёт в catch.
Загрузка данных с авторизацией (Bearer token)
const token = 'ваш_токен_доступа';
fetch('https://api.example.com/secure-data', {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json'
}
})
.then(response => {
if (!response.ok) throw new Error('Доступ запрещён');
return response.json();
})
.then(data => console.log('Защищённые данные:', data));
Заголовок Authorization передаётся в объекте headers. Без него сервер может вернуть 401.
Получение данных с таймаутом (прерывание запроса)
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5 секунд
fetch('https://httpstat.us/200?sleep=10000', { signal: controller.signal })
.then(response => response.text())
.then(data => console.log('Данные:', data))
.catch(err => {
if (err.name === 'AbortError') {
console.error('Запрос прерван по таймауту');
} else {
console.error('Ошибка:', err);
}
})
.finally(() => clearTimeout(timeoutId));
AbortController даёт возможность отменить запрос. После вызова abort() fetch выбросит исключение AbortError.
Чтение data-атрибутов элементов
const card = document.querySelector('.card');
const id = card.dataset.id; // data-id
const type = card.dataset.itemType; // data-item-type (камелкейс)
console.log('ID карточки:', id, 'Тип:', type);
ID карточки: 12345 Тип: premium
Атрибуты data-* доступны через свойство dataset. Имена преобразуются в camelCase (data-item-type → itemType).
Получение загруженного файла из input[type=file] как Base64
const fileInput = document.getElementById('avatar');
const file = fileInput.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function(e) {
const base64 = e.target.result;
console.log('Файл в Base64 (первые 100 символов):', base64.substring(0,100));
};
reader.readAsDataURL(file);
}
Файл в Base64 (первые 100 символов): data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...
FileReader позволяет асинхронно прочитать содержимое выбранного файла. Метод readAsDataURL возвращает DataURL, удобный для предпросмотра.
Обработка потоковых данных (Streaming) с fetch
async function readStream() {
const response = await fetch('https://example.com/large-file.txt');
const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
result += decoder.decode(value, { stream: true });
}
console.log('Полный текст:', result);
}
Полезно для больших данных, когда ответ приходит частями. Можно обрабатывать каждую порцию по мере поступления.