В чем основное отличие http методов GET и POST

Мне бы очень хотелось понять основную, (какую-то скрытую разницу) между http методом GET и POST. Что я знаю сейчас:

  1. GET мы отправляет запрос на сервер, для получения чего-то т.е выдача сервером какой-то информации клиенту. Для примера, сервер отдаёт какую-то информацию, допустим, имя и логин пользователя, который зашёл на сайт, для того, что бы отобразить её где-то на странице. Так же Get запрос может отдавать целые страницы в формате HTML или других форматах.
  2. POST это отправка данных на сервер. Т.е к примеру обновил данные и они отправились на сервер, или же ввел логин и пароль и они отправились на сервер.

Так же, знаю что к примеру в адресной строке при GET запросе, мы видим переданные данные. А у POST вроде они не в адресной строке, а в теле хранятся и так же вроде шифруются. (Интересно можно ли в инструментах разработчика их увидеть). И ещё знаю что в GET ВРОДЕ данные, которые вернул метод, они кешируются, а в POST вроде нет. Но говорят что к примеру при отправке данных необязательно использовать POST можно и GET и наоборот.

И вот мой вопрос: Что я упустил, какие ещё есть разницы или что я написал не так выше?


Ответы (1 шт):

Автор решения: Ivan Shatsky

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

  1. Объём данных, которые можно передать на сервер методом GET, ограничен объёмом примерно в 2 Кб; метод POST не имеет (теоретических) ограничений на объём передаваемых данных.

  2. Метод GET относится к идемпотентным методам, а метод POST - к неидемпотентным. Немного подробнее про (не)идемпотентность можно почитать на MDN.


Развёрнутый ответ

Вы правы в том, что и с помощью метода GET, и с помощью метода POST можно отправить данные на сервер. Оба метода возвращают какой-то ответ, который в том числе может являться и HTML-страницей, предназначенной для рендера в браузере.

Действительно, при передаче данных методом GET данные включаются в строку запроса (и к тому же должны содержать только разрешённые символы; все остальные байты должны быть закодированы в соответствии с правилами, описанными в RFC 3986, и более известными как URL encode). В силу исторических причин длина строки запроса обычно ограничена лимитом примерно в 2 Кб, хотя тут уже практическая ситуация больше зависит от используемых браузера и веб-сервера. Тело запроса для HTTP-метода GET, в отличии от метода POST, не предусмотрено. С помощью метода POST данные обычно передают в теле запроса, и тут уже ограничений на объём этих данных теоретически нет (практически они как правило есть всегда, и задаются на стороне веб-сервера). При этом никто не мешает включить в строку запроса метода POST дополнительные данные тем же способом, что и для метода GET, или вообще использовать его с пустым телом запроса - тут уже всё зависит от того, что от клиента ожидает серверное приложение.

Но главное отличие, о котором не упомянул ни один из комментаторов выше - это то, что метод GET относится к идемпотентным методам, а метод POST - к неидемпотентным. Вкратце, предполагается, что идемпотентные методы не могут вызвать изменения в состоянии сервера (которые, соответственно, могут повлиять на ответы от этого сервера в будущем), в отличие от неидемпотентных. Но это в теории. Реальность временами может расходиться с теорией.

Небольшой пример. Если у вас на сайте есть форма для поиска, данные, введенные в эту форму, обычно передаются на сервер методом GET, поскольку на состояние сервера они не повлияют, то есть если раньше сервер по некоторому запросу показывал определённую страницу, он не станет после этого показывать по тому же запросу какую-то другую страницу. Если же вы, предположим, публикуете какой-то пост в блоге, или комментарий к какому-то посту, то в этом случае данные должны быть переданы на сервер методом POST - ведь после этого страница со списком постов (или страница поста с комментариями) начинает отображать новую информацию, то есть состояние сервера изменяется.

И нет, при отправке данных методом POST они не "шифруются". Существуют стандартные методы инкапсуляции данных в тело POST-запроса (application/x-www-form-urlencoded, multipart/form-data, application/json и т.д.), хотя никто не мешает вам передать в теле запроса любые бинарные данные. И да, конечно, эти данные доступны для просмотра в инструментах разработчика (DevTools), как в "сыром" (raw), так и в "распарсенном" (parsed) виде.

А что касается собственно шифрования, то им занимается не HTTP, а транспортный протокол TLS (который в молодости назывался SSL). При использовании TLS, то есть при коммуникации по HTTPS-протоколу, зашифрованы будут и POST, и GET запросы. Другими словами, если вы гарантированно знаете, что доступ к веб-странице может быть осуществлён только по HTTPS-протоколу, вы можете передать на сервер логин и пароль из формы на странице входа методом GET, и они не будут доступны для анализа никакой третьей стороне, которая теоретически может слушать канал связи. Но сама строка запроса при этом скорее всего будет сохранена в истории браузера вместе с логином и паролем, что в общем случае не очень хорошо, поэтому для передачи подобных конфиденциальных данных всё-таки обычно стараются использовать метод POST.

→ Ссылка