Отправка POST данных на сервер с помощью JavaScript

Раздел: Frontend -> Отправка HTTP запросов

Отправка 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" }

POST запросы - comments

En
Js post (javascript)