Методы HTTP: что делает POST-запрос и чем он отличается от GET

POST-запрос отправляет данные на сервер в теле запроса, а GET получает их по адресу с параметрами.

Разобрали все методы HTTP по стандарту RFC 9110, проверили примеры curl и Python на живом сервере и собрали частые ошибки: 405, пустой JSON и повторная отправка формы.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2924 статьи автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3578 экспертных мнений Подписаться на Телеграм-канал
Обложка: Методы HTTP: что делает POST-запрос и чем он отличается от GET

POST-запрос отправляет данные на сервер: логин из формы, новый заказ, JSON для API. Данные едут в теле запроса, а не в адресе страницы, и сервер решает, что с ними сделать: создать запись, запустить обработку, отправить письмо.

Кроме POST у протокола HTTP есть ещё восемь стандартных методов. GET получает данные, PUT заменяет запись целиком, PATCH правит её часть, DELETE удаляет, HEAD отдаёт только заголовки. Ниже каждый метод с живым примером запроса и ответа. Если слово «API» пока звучит туманно, начните с разбора что такое API простыми словами.

CheckroiCheckroiПодборка курсов по REST108 курсов • 20 школСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Что такое HTTP-метод и где он стоит в запросе

Рой отправляет HTTP-запрос из терминала на ноутбуке

HTTP-метод — первое слово запроса. Он говорит серверу, что клиент хочет сделать с ресурсом по указанному адресу. Сам протокол и его место среди других мы разбирали в статье про сетевые протоколы.

Так выглядит POST-запрос «изнутри», в текстовом виде HTTP/1.1:

POST /post HTTP/1.1
Host: httpbin.org
Content-Type: application/json
Content-Length: 36

{"name": "anna", "course": "python"}

В запросе три части:

  1. Стартовая строка: метод POST, путь /post и версия протокола.
  2. Заголовки: адрес сайта, тип данных, длина тела.
  3. Тело после пустой строки. Здесь лежат сами данные, их ещё называют полезной нагрузкой, или payload.

У GET-запроса стартовая строка и заголовки такие же, а тела обычно нет. Все параметры он передаёт в адресе.

Шпаргалка: все методы HTTP в одной таблице

Методы описаны в стандарте RFC 9110 «HTTP Semantics», раздел 9 «Methods», а PATCH вынесен в отдельный RFC 5789. Два свойства из таблицы стоит запомнить сразу.

  • Безопасный метод ничего не меняет на сервере, он только читает.
  • Идемпотентный метод можно повторить десять раз подряд, и результат будет как после одного раза.
Метод Что делает Тело запроса Безопасный Идемпотентный
GET получает данные нет да да
HEAD как GET, но без тела ответа нет да да
POST отправляет данные на обработку, создаёт запись да нет нет
PUT создаёт или целиком заменяет ресурс да нет да
PATCH меняет часть ресурса да нет нет
DELETE удаляет ресурс обычно нет нет да
OPTIONS спрашивает, какие методы доступны обычно нет да да
TRACE возвращает запрос эхом, для отладки нет да да
CONNECT открывает туннель через прокси нет нет нет

Это и есть основные виды HTTP-запросов. В разговоре разработчики называют их по-русски: «гет-запрос», «пост», «пут», «патч», «делит».

Списки безопасных и идемпотентных методов взяты из стандарта дословно: безопасны GET, HEAD, OPTIONS и TRACE, идемпотентны PUT, DELETE и все безопасные. Про PATCH в RFC 5789 сказано прямо: он ни безопасный, ни идемпотентный.

На практике браузер или библиотека могут сами повторить идемпотентный запрос при обрыве связи. С POST так не поступают: повтор может создать второй заказ или списать деньги дважды.

Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

GET-запрос: получить данные

GET встречается в интернете чаще остальных методов. Каждый раз, когда вы открываете страницу или картинку, браузер шлёт GET. Параметры идут в адресе после знака вопроса: ?city=kazan&page=2.

Проверим на открытом тестовом сервере httpbin.org, который возвращает обратно всё, что получил. Команда для терминала:

curl "https://httpbin.org/get?city=kazan&page=2"

Ответ (сокращён до главного):

{
  "args": {
    "city": "kazan",
    "page": "2"
  },
  "url": "https://httpbin.org/get?city=kazan&page=2"
}

Сервер разобрал строку запроса и увидел два параметра. Тело GET-запросу не нужно, и стандарт прямо советует его не отправлять: у тела в GET нет определённого смысла, а часть серверов отвергает такие запросы.

Длина адреса тоже не бесконечна. RFC 9110 в разделе 4.1 рекомендует поддерживать адреса длиной не меньше 8000 байт. Это рекомендация стандарта, а реальный предел задают настройки конкретного сервера, прокси и браузера. Поэтому большие объёмы данных через GET не передают.

POST-запрос: отправить данные

POST нужен, когда данные надо передать серверу: заполненная форма, загрузка файла, новый объект в базе через API. Данные лежат в теле запроса, а заголовок Content-Type сообщает, в каком они формате.

POST с JSON

Так общаются почти все современные API. Данные пишутся в формате JSON:

curl -X POST https://httpbin.org/post \
  -H "Content-Type: application/json" \
  -d '{"name": "anna", "course": "python"}'

Фрагмент ответа:

{
  "json": {
    "course": "python",
    "name": "anna"
  },
  "url": "https://httpbin.org/post"
}

Сервер прочитал тело, увидел тип application/json и разобрал данные в объект.

POST из HTML-формы

Обычная форма на сайте по умолчанию отправляет данные в виде login=anna&remember=1 с типом application/x-www-form-urlencoded. В curl это ключ -d без заголовка:

curl https://httpbin.org/post -d "login=anna&remember=1"

В ответе httpbin положил эти поля в раздел "form": {"login": "anna", "remember": "1"}. Файлы формы отправляет в третьем формате, multipart/form-data, и это тоже только POST.

Что сервер отвечает на POST

Если запрос создал новую запись, стандарт советует ответить кодом 201 Created и заголовком Location с адресом новой записи. На практике многие API отвечают просто 200 OK. Наш тестовый httpbin ничего не создаёт и всегда возвращает 200.

Чем GET отличается от POST

Рой сравнивает два конверта с надписями GET и POST

Это классический вопрос на собеседовании тестировщика и backend-разработчика. Сводка различий:

GET POST
Где данные в адресе, после «?» в теле запроса
Задача прочитать отправить, создать, обработать
Меняет данные на сервере не должен да
Повтор запроса безвреден может создать дубль
Кеш браузера и прокси кешируется почти никогда
История браузера и закладки адрес с параметрами сохраняется тело не сохраняется
Объём данных ограничен длиной адреса ограничен настройками сервера
Файлы нельзя можно

Строка про кеш тоже из стандарта: RFC 9110 описывает правила кеширования для GET, HEAD и POST, но там же оговорено, что подавляющее большинство кешей работает только с GET и HEAD.

Частое заблуждение: «POST безопаснее, потому что данных не видно». Без HTTPS тело запроса читается в сети так же легко, как адрес. Разница в другом: адрес GET-запроса оседает в истории браузера, логах сервера и заголовке Referer. Поэтому пароли и личные данные отправляют через POST и только по HTTPS.

PUT и PATCH: заменить или поправить

Оба метода меняют существующую запись, но по-разному.

  • PUT присылает ресурс целиком. Сервер заменяет старую версию новой, а если записи не было, может её создать.
  • PATCH присылает только изменения. Остальные поля сервер не трогает.

Пример. У пользователя есть имя, курс и город. Чтобы сменить курс, PATCH достаточно отправить одно поле:

curl -X PATCH https://httpbin.org/patch \
  -H "Content-Type: application/json" \
  -d '{"course": "sql"}'

С PUT так нельзя. Если отправить PUT только с полем course, правильно сделанный сервер сохранит запись без имени и города. Отсюда правило: PUT шлёт полную версию, PATCH шлёт разницу.

По RFC 9110 PUT идемпотентен: десять одинаковых PUT дают ту же запись, что и один. Если записи не было и PUT её создал, сервер обязан ответить 201, а при замене существующей ответит 200 или 204.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

DELETE, HEAD, OPTIONS и редкие методы

DELETE

Удаляет ресурс по адресу. Удачный ответ обычно 204 No Content (удалено, тело ответа пустое) или 200 с описанием результата. Повторный DELETE той же записи ничего нового не удалит, поэтому метод идемпотентный, хотя второй ответ может прийти с кодом 404.

HEAD

Работает как GET, но сервер возвращает только заголовки. Удобно, чтобы узнать размер файла или проверить, жива ли страница, не скачивая её. В curl это ключ -I:

curl -I https://httpbin.org/get

HTTP/2 200
content-type: application/json
content-length: 256

OPTIONS

Спрашивает сервер, какие методы доступны по адресу. Чаще всего его отправляет сам браузер: перед кросс-доменным запросом с JSON он шлёт предварительный OPTIONS (его называют preflight-запросом CORS) и только после разрешения отправляет основной.

TRACE и CONNECT

В обычной разработке они почти не встречаются. TRACE возвращает запрос эхом для отладки, и на рабочих серверах его часто отключают, чтобы не раскрывать заголовки. CONNECT открывает туннель через прокси-сервер, им пользуется браузер при работе через HTTPS-прокси.

Методы в REST API: как они ложатся на CRUD

В REST API методы работают как глаголы, а адрес обозначает предмет. Четыре базовые операции с данными, CRUD (создать, прочитать, обновить, удалить), раскладываются по методам так:

Операция Метод и адрес Что произойдёт Типичный удачный ответ
Создать POST /users новый пользователь, номер выдаст сервер 201 Created
Прочитать список GET /users список пользователей 200 OK
Прочитать одного GET /users/42 карточка пользователя 42 200 OK
Заменить PUT /users/42 карточка 42 целиком новая 200 OK или 204 No Content
Поправить PATCH /users/42 изменились только присланные поля 200 OK или 204 No Content
Удалить DELETE /users/42 карточки 42 больше нет 204 No Content

Такие пары «метод + адрес» проверяют автотесты API, а чем их пишут, разобрано в статье про инструменты автоматизации тестирования.

По адресам видна разница между POST и PUT. POST шлют на адрес коллекции /users, и номер новой записи выбирает сервер. PUT шлют на конкретный адрес /users/42: клиент сам знает, какую запись создаёт или заменяет.

Так принято, но стандарт этого не требует. Встречаются API, где почти всё идёт через POST, например JSON-RPC или GraphQL: там действие указано в теле запроса. Поэтому перед работой с чужим API читайте его документацию, а не угадывайте по названию метода. Проектирование таких интерфейсов разбирают в курсах по REST API.

Как отправить HTTP-запрос самому

Для тренировки хватит трёх инструментов, и все бесплатные.

curl в терминале

Утилита встроена в macOS, в большинство дистрибутивов Linux и в актуальные версии Windows 10 и 11. Главные ключи из документации curl:

Ключ Что делает
-X МЕТОД задаёт метод: PUT, PATCH, DELETE
-H "Заголовок: значение" добавляет заголовок
-d "данные" кладёт данные в тело и сам переключает метод на POST
--json '{...}' отправляет JSON и сам ставит заголовки Content-Type и Accept, работает с curl 7.82
-I отправляет HEAD
-i показывает заголовки ответа вместе с телом

Python и библиотека requests

На Python каждый метод вызывается одноимённой функцией библиотеки requests. Если Python только осваиваете, сначала посмотрите, как создать и запустить файл Python в VS Code. Сам скрипт:

import requests

r = requests.get("https://httpbin.org/get", params={"city": "kazan", "page": 2})
print(r.status_code, r.url)

r = requests.post("https://httpbin.org/post", json={"name": "Анна", "course": "python"})
print(r.status_code, r.json()["json"])

r = requests.patch("https://httpbin.org/patch", json={"course": "sql"})
print(r.status_code, r.json()["json"])

r = requests.delete("https://httpbin.org/get")
print(r.status_code, r.headers["Allow"])

Вывод при запуске:

200 https://httpbin.org/get?city=kazan&page=2
200 {'course': 'python', 'name': 'Анна'}
200 {'course': 'sql'}
405 HEAD, OPTIONS, GET

Параметр json= сам превращает словарь в JSON и ставит нужный заголовок. Последняя строка показывает ошибку 405: адрес /get не принимает DELETE, о ней ниже. Порядок методов в заголовке Allow у httpbin меняется от запуска к запуску, на смысл это не влияет.

Инструменты разработчика в браузере

Откройте любой сайт, нажмите F12 и перейдите на вкладку Network (в русском интерфейсе Chrome она называется «Сеть»). Обновите страницу: в столбце Method (его включают правым кликом по заголовку таблицы) видно, какие запросы браузер отправил. Отправьте форму на сайте, и в списке появится POST, а во вкладке Payload будет его тело.

Для регулярной работы с API тестировщики и разработчики берут отдельные клиенты с сохранением запросов и коллекций. Курсы по одному из самых известных собраны в каталоге курсов по Postman.

Частые ошибки с HTTP-методами

Шпаргалка по методам HTTP и коды ответов сервера на столе

405 Method Not Allowed. Сервер знает метод, но по этому адресу его не принимает. По стандарту он обязан вернуть заголовок Allow со списком разрешённых методов, его и смотрите:

curl -i -X DELETE https://httpbin.org/get

HTTP/2 405
allow: GET, HEAD, OPTIONS

415 Unsupported Media Type или пустые данные на сервере. Чаще всего забыт заголовок Content-Type: application/json. Без него curl с ключом -d отправит данные как форму, и сервер не найдёт JSON.

Окно «Подтвердите повторную отправку формы». Пользователь обновил страницу после POST, и браузер готов отправить форму второй раз. Решение на стороне сайта: после успешного POST перенаправить пользователя на обычную страницу через ответ 303 See Other.

GET, который что-то меняет. Ссылка вида /delete?id=5 выглядит удобно, пока поисковый робот или предзагрузка браузера не пройдут по ней сами. Всё, что меняет данные, отправляйте POST, PUT, PATCH или DELETE.

PUT вместо PATCH. Отправили PUT с одним полем и потеряли остальные. Для частичной правки нужен PATCH, если API его поддерживает. Какие методы принимает конкретный API, написано в его документации, это первое, что проверяют.

Где научиться работать с HTTP и API

Чтобы отправить запрос, хватит этой шпаргалки. Спроектировать своё API, выбрать коды ответов и написать автотесты на эндпоинты сложнее, это разбирают в курсах по REST API, тестированию и бэкенду. Ниже программы из каталога, их можно сравнить по цене, длительности и формату.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
PHP-разработчик. Базовый уровень
Перейти на сайт курса
SkillboxSkillbox81 107 ₽5227 ₽/мес.3 месяцаОбзор курса
Профессия «Системный аналитик с нуля до middle»
Перейти на сайт курса
НетологияНетология144 550 ₽6022 ₽/мес.15 месяцевОбзор курса
Профессия «Java-разработчик с нуля»
Перейти на сайт курса
НетологияНетология131 700 ₽5625 ₽/мес.11 месяцевОбзор курса
JavaScript
Перейти на сайт курса
SkillboxSkillbox63 829 ₽4086 ₽/мес.3 месяцаОбзор курса

Больше программ — в полном каталоге курсов по REST

Если HTTP нужен вам как часть профессии, посмотрите план, как стать backend-разработчиком и разбор формата JSON: с методами HTTP и JSON бэкенд-разработчик работает с первых недель.

Часто задаваемые вопросы

Что такое POST-запрос простыми словами?

Это HTTP-запрос, который отправляет данные на сервер: заполненную форму, JSON для API, файл. Данные лежат в теле запроса, а сервер решает, что с ними сделать, например создать новую запись.

Чем GET-запрос отличается от POST?

GET получает данные и передаёт параметры в адресе после «?», его безопасно повторять и можно кешировать. POST отправляет данные в теле запроса и обычно что-то меняет на сервере, поэтому повтор может создать дубль.

Чем PUT отличается от PATCH?

PUT присылает ресурс целиком и заменяет старую версию, а PATCH присылает только изменённые поля. По стандарту PUT идемпотентный, PATCH нет.

Можно ли отправить тело в GET-запросе?

Технически можно, но стандарт RFC 9110 советует этого не делать: у тела в GET нет определённого смысла, и часть серверов такие запросы отвергает. Параметры для GET передают в строке адреса.

Какой код ответа сервер возвращает на POST?

Если запрос создал новую запись, стандарт советует ответ 201 Created с заголовком Location, где указан адрес записи. Многие API отвечают просто 200 OK, а если метод по адресу не принимается, приходит 405 Method Not Allowed.

Как отправить POST-запрос без программирования?

Проще всего через curl в терминале: команда curl https://httpbin.org/post -d "name=anna" сама отправит POST. Посмотреть запросы, которые шлёт сайт, можно в инструментах разработчика браузера на вкладке Network.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!