← Назад к вопросам

Есть ли body в server response?

1.0 Junior🔥 241 комментариев
#API и сетевые протоколы

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Есть ли body в server response?

Да, body может присутствовать в server response, но его наличие зависит от метода HTTP запроса и статуса ответа. Это один из важных аспектов HTTP протокола, который часто упускают junior разработчики.

Когда body обязателен

Для методов GET, POST, PUT, PATCH: body может содержать данные, которые вернул сервер (JSON, HTML, файл и т.д.).

Пример GET запроса:

// Запрос
GET /api/v1/users/123 HTTP/1.1
Host: api.example.com

// Ответ
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 145

{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com"
}

Пример POST запроса:

// Запрос
POST /api/v1/users HTTP/1.1
Host: api.example.com
Content-Type: application/json

{"name": "Jane", "email": "jane@example.com"}

// Ответ (с body)
HTTP/1.1 201 Created
Content-Type: application/json

{
  "id": 124,
  "name": "Jane",
  "email": "jane@example.com"
}

Когда body НЕ должно быть

Метод DELETE с статусом 204 (No Content):

// Запрос
DELETE /api/v1/users/123 HTTP/1.1

// Ответ (БЕЗ body)
HTTP/1.1 204 No Content
Content-Length: 0

Метод HEAD: это вариант GET, который возвращает только заголовки, БЕЗ body.

// Запрос
HEAD /api/v1/users/123 HTTP/1.1

// Ответ (БЕЗ body)
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 145

Статусы ответов и body

1xx (Информационные): обычно БЕЗ body

  • 100 Continue
  • 101 Switching Protocols

2xx (Успешные): MAY содержать body

  • 200 OK → с body (данные, JSON)
  • 201 Created → с body (созданный ресурс)
  • 202 Accepted → может быть body
  • 204 No Content → НИКОГДА не содержит body
  • 205 Reset Content → НИКОГДА не содержит body
  • 206 Partial Content → с body (часть файла)

3xx (Перенаправление): обычно БЕЗ body

  • 301 Moved Permanently
  • 302 Found
  • 304 Not Modified → НИКОГДА не содержит body

4xx (Ошибки клиента): обычно с body (описание ошибки)

  • 400 Bad Request → с body (причина)
  • 401 Unauthorized → может быть body
  • 404 Not Found → с body (описание)
  • 409 Conflict → с body (детали конфликта)

5xx (Ошибки сервера): обычно с body (описание ошибки)

  • 500 Internal Server Error → с body
  • 503 Service Unavailable → может быть body

Практические примеры на Node.js

Express.js — отправка response с body:

// GET с body
app.get('/api/users/:id', (req, res) => {
  res.status(200).json({ id: 1, name: 'John' });
});

// POST с body
app.post('/api/users', (req, res) => {
  const newUser = { id: 2, ...req.body };
  res.status(201).json(newUser); // 201 Created с body
});

// DELETE без body
app.delete('/api/users/:id', (req, res) => {
  res.status(204).send(); // 204 No Content, body пустой
});

// HEAD без body
app.head('/api/users/:id', (req, res) => {
  res.status(200).end(); // Только заголовки
});

// Ошибка с body
app.get('/api/invalid', (req, res) => {
  res.status(400).json({ 
    error: 'Bad Request',
    details: 'Missing required field'
  });
});

Проверка наличия body в ответе:

const axios = require('axios');

const response = await axios.get('/api/users/123');

// response.data содержит body
console.log(response.data);

// response.status содержит статус
console.log(response.status);

// response.headers содержит заголовки
console.log(response.headers);

Content-Length заголовок

Content-Length указывает размер body в байтах. Это важно для правильной обработки response.

// Если Content-Length: 0, то body пустой
// Если Content-Length отсутствует, используется Transfer-Encoding: chunked

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 25

{"id": 1, "name": "John"}

Streaming responses (большие файлы)

Для больших файлов или потоковых данных body передаётся частями.

Пример:

app.get('/api/download/large-file', (req, res) => {
  res.setHeader('Content-Type', 'application/octet-stream');
  res.setHeader('Content-Disposition', 'attachment; filename="file.zip"');
  
  // Передаём файл потоком
  const fileStream = fs.createReadStream('/path/to/large-file.zip');
  fileStream.pipe(res);
});

// Range запросы (для видео, загрузок с паузой)
app.get('/api/stream/video', (req, res) => {
  const file = fs.statSync('video.mp4');
  const fileSize = file.size;
  const range = req.headers.range;
  
  if (range) {
    const parts = range.replace(/bytes=/, '').split('-');
    const start = parseInt(parts[0], 10);
    const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1;
    
    res.writeHead(206, {
      'Content-Range': `bytes ${start}-${end}/${fileSize}`,
      'Content-Length': end - start + 1,
      'Content-Type': 'video/mp4'
    });
    
    fs.createReadStream('video.mp4', { start, end }).pipe(res);
  } else {
    res.writeHead(200, { 'Content-Length': fileSize });
    fs.createReadStream('video.mp4').pipe(res);
  }
});

Важное правило: 204 и 304

Статусы 204 и 304 НИКОГДА не должны содержать body, даже пустое. Заголовок Content-Length должен быть 0 или отсутствовать.

// Правильно
res.status(204).end();

// Неправильно
res.status(204).json({}); // Некорректно!
res.status(204).send(''); // Некорректно!

Чеклист

  • Body может быть в любом ответе, КРОМЕ 204, 205, 304 и 1xx
  • Content-Length или Transfer-Encoding указывают размер body
  • HEAD не возвращает body, только заголовки
  • DELETE обычно возвращает 204 (без body) или 200 (с body результата)
  • Всегда проверяй статус кода и наличие body при разработке API