Тело запроса: JSON, form-data, urlencoded, файлы
↑ 1.2 HTTP и REST для не-разработчиков · ← Предыдущая · → Следующая
Зачем это аналитику и PM
Одни и те же поля «имя и файл» уезжают тремя разными упаковками. Пока формат не назван, разработчик экрана и разработчик сервера собирают два несовместимых запроса и спорят на приёмке.
План темы
- чем отличаются форматы
- как отправить файл
- как выбрать в Postman
Объяснение
Тело запроса — полезная нагрузка сообщения, то, что не поместили в адрес и заголовки. Формат тела задаёт заголовок Content-Type. Расширение файла на диске аналитика само по себе сервер не убеждает.
Как посылка. JSON — один аккуратный свёрток с подписями на каждом предмете. Urlencoded — открытка, где поля дописаны в одну строку, почти как query. Form-data — коробка с перегородками: в одном отсеке текст, в другом файл. Перепутать открытку и коробку значит, что получатель не найдёт вложение, даже если «все поля были».
Чем форматы отличаются
JSON — текст из объектов, списков и значений. Им описывают заказ, профиль, фильтр, если он не влез в адрес. Имена полей чувствительны к регистру. Лишняя запятая ломает весь разбор: это уже 400, а не ошибка одного поля.
application/x-www-form-urlencoded — пары имя=значение, соединённые &, с процентным кодированием. Так устроены старые HTML-формы без файлов. Вложенный заказ из нескольких позиций здесь передавать неудобно: нет естественных объектов и списков.
multipart/form-data режет тело на части. У каждой части своё имя поля и свой кусок данных. Текст и файл едут вместе. Граница между частями — служебная строка, её ставит клиент. В требованиях её не выдумывают руками.
| Формат | Когда уместен | Чего не ждать |
|---|---|---|
| JSON | Карточки, команды, вложенные поля | Вложения файла без отдельной договорённости |
| urlencoded | Простая форма без файла | Списков и вложенных объектов |
| form-data | Файл плюс поля рядом | Что сервер сам угадает JSON внутри файла |
| Без тела | Чтение, где всё уже в URL | Полей «ещё и в теле на всякий случай» |
GET с телом в постановку лучше не закладывать. Часть клиентов и промежуточных узлов тело у GET отбрасывает. Условия чтения кладут в query или переносят операцию на POST, если фильтр большой, и прямо пишут, что это чтение.
Файл и Postman
Файл — отдельная часть form-data: имя поля (attachment), имя файла и содержимое. Рядом в других частях едут orderId или комментарий. Ограничение размера, допустимые типы и что будет при повторе загрузки описывают в задаче. Фраза «приложите файл» не говорит, обновится старый файл или появится второй.
В Postman вид тела выбирают на вкладке Body. Для JSON обычно режим raw и указание JSON, для пар полей — x-www-form-urlencoded, для файла — form-data и тип File у нужной строки.
Примеры
JSON для создания. Это схема.
{
"sku": "MUG-1",
"qty": 2,
"comment": "хрупкое"
}Та же пара полей как urlencoded, без вложенности:
sku=MUG-1&qty=2&comment=%D1%85%D1%80%D1%83%D0%BF%D0%BA%D0%BE%D0%B5Схема частей form-data. Это не сырой дамп с настоящей границей, а список того, что должно уехать.
part orderId = 1042
part comment = хрупкое
part attachment = file mug.png
Content-Type всего запроса: multipart/form-dataЖивой POST на httpbin возвращает присланное тело эхом. Удобно проверить, что уехал JSON, а не форма. Состав ответа смотрите у сервиса, здесь только команда.
curl -sS -X POST "https://httpbin.org/post" -H "Content-Type: application/json" -d "{\"sku\":\"MUG-1\",\"qty\":2}"Нюансы и подводные камни
- Неверная запятая в JSON роняет весь запрос. В баге приложите тело как текст, не пересказ.
- Число и строка
"2"— разные значения JSON. В контракте тип назван явно. - Urlencoded не умеет файл. Если в сценарии есть вложение, это form-data или отдельный метод загрузки, не «та же форма».
Практика
Для сценария «создать заявку с одним вложением» выберите формат, перечислите поля и отметьте, которое является файлом.
Ожидаемый результат: назван multipart/form-data, у файла есть имя поля, у текстовых полей — типы. Рядом сказано, что JSON этого вложения не заменяет. Лимит размера либо указан командой, либо стоит вопрос, а не выдуманное число мегабайт.
Вопросы с ответами
Почему сервер не читает JSON, который глазом выглядит верным?
Чаще всего заголовок
Content-Typeнеapplication/json, либо в тексте лишняя запятая. Глаз видит объект, парсер видит набор байтов другого типа или сломанный текст.
Когда хватает urlencoded?
Когда полей мало, они плоские и файла нет: старая форма входа или простой фильтр. Заказ с позициями и вложением так не описывают без боли.
Как в требованиях назвать загрузку файла?
Формат multipart, имя поля файла, допустимые типы, максимальный размер и что делает повтор: замена или второй файл. Без этого «прикрепить» на макете не контракт.