Отправка POST данных на сервер с помощью JavaScript
Отправка POST запросов в JavaScript
POST запросы применяются для передачи данных на сервер. Современный стандарт - API fetch с использованием async/await.
Как отправить POST запрос с JSON данными?
async function postData(url = '', data = {}) {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('HTTP error ' + response.status);
return response.json();
}
postData('https://jsonplaceholder.typicode.com/posts', { title: 'foo', body: 'bar', userId: 1 })
.then(data => console.log(data))
.catch(err => console.error(err));Js post (post запросы)
Пояснение: функция fetch принимает URL и объект параметров. Указывается метод POST, заголовок Content-Type для JSON, тело запроса преобразуется в строку через JSON.stringify. Ответ проверяется на успешность, затем извлекается JSON. Использование async/await делает код читаемым.
Типичные ошибки: забыли указать заголовок Content-Type - сервер может не распознать данные; не проверяется статус ответа (response.ok); попытка повторного вызова response.json() после первого использования - поток данных закрывается. Решение - всегда проверять ok и обрабатывать ошибки в catch.
Как отправить POST запрос с помощью XMLHttpRequest?
const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://jsonplaceholder.typicode.com/posts');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(JSON.parse(xhr.responseText));
} else {
console.error('Request failed. Status:', xhr.status);
}
};
xhr.onerror = function() {
console.error('Network error');
};
xhr.send(JSON.stringify({ title: 'foo', body: 'bar', userId: 1 }));Пояснение: XMLHttpRequest - устаревший, но ещё используемый API. Создаётся объект, вызывается open с методом и URL, устанавливаются заголовки, обработчики событий onload и onerror, и отправляются данные.
Проблемы: громоздкий код, отсутствие поддержки промисов, сложность обработки ошибок. Для современных проектов рекомендуется fetch.
Как отправить POST запрос с помощью axios?
axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
})
.then(response => console.log(response.data))
.catch(error => console.error(error));Пояснение: axios - популярная библиотека, упрощающая работу с HTTP. Метод post принимает URL и объект данных, автоматически преобразует в JSON и устанавливает заголовки. Ответ содержит свойство data с телом.
Ошибки: необходимо подключать библиотеку (CDN или npm). При использовании в браузере без Node.js возможны проблемы с CORS, если сервер не разрешает.
Как отправить файл или форму с помощью POST?
const formData = new FormData();
formData.append('username', 'Alice');
formData.append('avatar', fileInput.files[0]);
fetch('https://example.com/upload', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));Пояснение: объект FormData автоматически устанавливает multipart/form-data. Не нужно явно указывать Content-Type - браузер задаёт его сам с границей. Это подходит для загрузки файлов.
Проблемы: если сервер ожидает другой формат (например, application/x-www-form-urlencoded), FormData не подойдёт. Также при передаче файлов большого размера возможны тайм-ауты.
Как отправить данные в формате application/x-www-form-urlencoded?
const params = new URLSearchParams();
params.append('username', 'Alice');
params.append('password', 'secret');
fetch('https://example.com/login', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params
})
.then(response => response.text())
.then(result => console.log(result))
.catch(err => console.error(err));Пояснение: URLSearchParams преобразует объект в строку вида key=value&key2=value2. Заголовок Content-Type устанавливается вручную. Ответ часто получают как текст, а не JSON.
Ошибки: если не указать заголовок, браузер может отправить с неправильным типом; значения не кодируются автоматически - но URLSearchParams это делает.
// Пример 1: отправка с пользовательскими заголовками и обработка прогресса загрузки
async function uploadFileWithProgress(url, file) {
const formData = new FormData();
formData.append('file', file);
const xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.upload.onprogress = (event) => {
if (event.lengthComputable) {
console.log(`Прогресс: ${Math.round((event.loaded / event.total) * 100)}%`);
}
};
const result = await new Promise((resolve, reject) => {
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new Error(`HTTP ${xhr.status}`));
}
};
xhr.onerror = () => reject(new Error('Network error'));
xhr.send(formData);
});
return result;
}
// Использование:
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', async (e) => {
const file = e.target.files[0];
try {
const data = await uploadFileWithProgress('/upload', file);
console.log('Результат:', data);
} catch (err) {
console.error('Ошибка:', err);
}
});// При загрузке файла размером 1 МБ:
// Прогресс: 45%
// Прогресс: 100%
// Результат: { success: true, url: '/uploads/photo.jpg' }// Пример 2: параллельные POST запросы с Promise.all
async function postMultipleItems(url, items) {
const promises = items.map(item =>
fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(item)
}).then(res => res.json())
);
return Promise.all(promises);
}
const items = [
{ name: 'item1', value: 10 },
{ name: 'item2', value: 20 },
{ name: 'item3', value: 30 }
];
postMultipleItems('https://api.example.com/batch', items)
.then(results => console.log('Все результаты:', results))
.catch(err => console.error('Ошибка в одном из запросов:', err));// Все результаты:
// [
// { id: 101, status: 'created' },
// { id: 102, status: 'created' },
// { id: 103, status: 'created' }
// ]// Пример 3: обработка ошибок с детальным разбором статусов
async function postWithErrorHandling(url, data) {
let response;
try {
response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
} catch (networkError) {
throw new Error('Сетевая ошибка: ' + networkError.message);
}
if (!response.ok) {
let errorBody;
try {
errorBody = await response.json();
} catch {
errorBody = await response.text();
}
throw new Error(`HTTP ${response.status}: ${JSON.stringify(errorBody)}`);
}
return response.json();
}
postWithErrorHandling('https://api.example.com/users', { name: 'Bob' })
.then(user => console.log('Создан пользователь:', user))
.catch(err => console.error('Детали ошибки:', err.message));// При ответе сервера со статусом 400:
// HTTP 400: {"error":"Name is required"}// Пример 4: отправка вложенного JSON с кастомным Content-Type
const complexData = {
user: { name: 'Alice', age: 30 },
tags: ['admin', 'editor'],
metadata: { created: new Date().toISOString() }
};
fetch('https://api.example.com/v2/profile', {
method: 'POST',
headers: {
'Content-Type': 'application/vnd.api+json',
'Authorization': 'Bearer token123'
},
body: JSON.stringify(complexData)
})
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));// Ответ сервера:
// { "id": 456, "status": "updated" }