> Как реализовать в HTTP заголовках сервис, который принимает JSON и отвечает текстом (JavaScript)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Тинькофф

Стек: JavaScript

> Пример ответа

Короткий ответ

HTTP-заголовки не управляют форматом тела ответа - за это отвечает заголовок Content-Type. Сервис, который принимает JSON и отвечает текстом, должен на запрос с Content-Type: application/json возвращать ответ с Content-Type: text/plain (или text/html). На стороне сервера достаточно прочитать тело запроса как JSON, обработать его и вернуть строку с соответствующим заголовком. Клиент при этом должен уметь обрабатывать ответ, отличный от JSON.

Подробное объяснение

HTTP-протокол разделяет метаданные запроса и ответа. Заголовки Content-Type и Accept описывают формат тела, но не являются обязательными для согласования - сервер сам решает, в каком формате вернуть ответ. Если сервер принимает JSON и отдаёт текст, это корректная ситуация: запрос содержит Content-Type: application/json, ответ - Content-Type: text/plain; charset=utf-8.

Важно понимать разницу:

  • Content-Type в запросе - формат тела запроса.
  • Content-Type в ответе - формат тела ответа.
  • Accept в запросе - предпочтения клиента, но сервер может их игнорировать.

Для реализации на JavaScript (Node.js, Express) нужно:

  1. Прочитать тело запроса как JSON (middleware express.json()).
  2. Обработать данные.
  3. Установить res.set('Content-Type', 'text/plain').
  4. Отправить строку через res.send().

Клиент (fetch, axios) должен проверять response.headers.get('content-type') и обрабатывать текст, а не пытаться парсить JSON.

На практике

В реальном API такой сценарий встречается при:

  • генерации отчётов или экспорте данных (JSON на вход, CSV/текст на выход);
  • проксировании запросов к внешним сервисам;
  • возврате ошибок в текстовом формате (например, text/plain для простоты логирования).

Важно помнить про кодировку: для текста всегда указывать charset=utf-8, чтобы избежать проблем с кириллицей. Также стоит явно обрабатывать ошибки парсинга JSON - если тело запроса невалидно, вернуть 400 с текстовым описанием ошибки.

Пример кода

JAVASCRIPT
// Express сервер
const express = require('express');
const app = express();
app.use(express.json());
app.post('/convert', (req, res) => {
try {
const data = req.body; // уже JSON
const text = `Получено: ${data.name}, возраст: ${data.age}`;
res.set('Content-Type', 'text/plain; charset=utf-8');
res.send(text);
} catch (err) {
res.status(400).set('Content-Type', 'text/plain').send('Некорректный JSON');
}
});
app.listen(3000);

Клиент на fetch:

JAVASCRIPT
const response = await fetch('/convert', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Иван', age: 30 })
});
const contentType = response.headers.get('content-type');
if (contentType.includes('text/plain')) {
const text = await response.text();
console.log(text);
}

Как отвечать на собеседовании

Начните с того, что заголовки не управляют форматом - это делает Content-Type. Затем опишите, что сервер может принимать один формат, а отдавать другой, и это нормально. Упомяните, что клиент должен быть готов к такому поведению и проверять Content-Type ответа. Если спросят про Accept - скажите, что это рекомендация, а не обязательство. Подчеркните важность обработки ошибок парсинга JSON и корректной кодировки.

Что проверяет интервьюер

  • понимание разницы между форматом запроса и ответа;
  • знание HTTP-заголовков Content-Type, Accept;
  • умение работать с middleware и обработкой ошибок в Express;
  • внимание к деталям: charset, статус-коды, обработка невалидного JSON.

Типичные ошибки

  • попытка вернуть JSON, когда нужен текст - забывают сменить Content-Type;
  • игнорирование charset=utf-8 - проблемы с кириллицей;
  • отсутствие обработки ошибок парсинга JSON - сервер падает с 500 вместо 400;
  • на клиенте всегда вызывают response.json(), не проверяя Content-Type - получают ошибку парсинга;
  • путают Content-Type запроса и ответа, думая, что они должны совпадать.

> Похожие задачи по frontend

Что такое контекст (this) в JavaScript

Уровень: juniorКатегория: Технические вопросы
Компания: YADRO, Garage Eight, циан, Soft_Media_Group, VK, Инити, Aston, Kaspersky, Centicore, IT-One, EdenAI, Сбер, TYMY, HolyWeb, Purrweb, ООО Снэп АйТи
Стек: JavaScript

Что такое event loop в JavaScript и как он работает с микрозадачами и макрозадачами

Уровень: juniorКатегория: Технические вопросы
Компания: amoCRM, Иннотех, Cyber Interactive, Альфа-банк, YADRO, Garage Eight, Kvando Technologies, циан, Soft_Media_Group, ООО Премиум ИТ Солюшен, VK, Kodix, РСХБ, LeverX, Инити, Aston, Газпромбанк, Домклик, IT-One, Софт Медиа Групп, МТГ Бизнес решения, Библио-Глобус, Rutube, Дом.рф, intelsy, Avito, Сфера, EdenAI, Сбер, Арго, TYMY, 1221 Systems, Исходный Код, Globaldrive, Кэтрид Диджитал, SmartWay, ООО Снэп АйТи
Стек: JavaScript

Как реализована отправка JSON в API

Уровень: seniorКатегория: Технические вопросы
Компания: Merlion
Стек: JavaScript

Какие типы могут быть ключами в JSON

Уровень: middleКатегория: Технические вопросы
Компания: Сбер
Стек: JavaScript

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью