Можно ли кешировать POST-методы в HTTP? - PullRequest
141 голосов
/ 09 марта 2009

С очень простой семантикой кэширования: если параметры одинаковы (и URL-адрес одинаков, конечно), то это хит. Это возможно? Рекомендуется

Ответы [ 9 ]

91 голосов
/ 09 марта 2009

Соответствующий RFC 2616 в разделе 9.5 (POST) позволяет кэшировать ответ на сообщение POST, если вы используете соответствующие заголовки.

Ответы на этот метод не кэшируются, если ответ включает в себя соответствующие поля заголовка Cache-Control или Expires. Тем не мение, ответ 303 (см. «Другое») может использоваться для направления пользовательского агента получить кешируемый ресурс.

Обратите внимание, что тот же RFC прямо указывает в разделе 13 (Кэширование в HTTP), что кеш должен сделать недействительной соответствующую сущность после запроса POST .

Некоторые методы HTTP ДОЛЖНЫ вызывать кеш для аннулирования объекта. Это либо субъект, упомянутый Request-URI или по расположению или Заголовки Content-Location (если есть). Эти методы:

  - PUT
  - DELETE
  - POST

Мне неясно, как эти спецификации могут обеспечить значимое кэширование.

63 голосов
/ 06 мая 2009

Согласно RFC 2616, раздел 9.5:

"Ответы на метод POST не являются кешируется, если ответ включает соответствующий Cache-Control или Истекает поля заголовка. "

Итак, ДА, вы можете кэшировать ответ на запрос POST, но только если он приходит с соответствующими заголовками. В большинстве случаев вы не хотите кэшировать ответ. Но в некоторых случаях - например, если вы не сохраняете какие-либо данные на сервере - это вполне уместно.

Обратите внимание, однако, что многие браузеры, включая текущий Firefox 3.0.10, не будут кэшировать POST-ответ независимо от заголовков. IE ведет себя умнее в этом отношении.

Теперь я хочу прояснить некоторую путаницу в отношении RFC 2616 S. 13.10. Метод POST для URI не «лишает законной силы ресурс для кэширования», как некоторые из них заявили здесь. Это делает ранее кэшированную версию этого URI устаревшей, даже если его заголовки управления кешем указывали свежесть большей продолжительности.

31 голосов
/ 09 марта 2009

Общий:

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

См. Раздел 9.1 HTTP 1.1 RFC 2616 S. 9.1 .

Кроме семантики метода GET:

Сам метод POST семантически предназначен для публикации чего-либо на ресурсе. POST не может быть кэширован, потому что если вы делаете что-то один раз против двух против трех раз, то вы каждый раз изменяете ресурс сервера. Каждый запрос имеет значение и должен быть доставлен на сервер.

Сам метод PUT семантически предназначен для размещения или создания ресурса. Это идемпотентная операция, но она не будет использоваться для кэширования, поскольку в это время могла произойти УДАЛЕНИЕ.

Сам метод DELETE семантически предназначен для удаления ресурса. Это идемпотентная операция, но она не будет использоваться для кэширования, поскольку в это время мог произойти PUT.

Относительно кэширования на стороне клиента:

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

Относительно кэширования прокси:

Прокси-HTTP-сервер, который пересылает ваше сообщение на сервер, никогда не кэширует ничего, кроме запроса GET или HEAD.

Относительно кэширования сервера:

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

Аннулирование ресурса:

Проверка HTTP 1.1 RFC 2616 S. 13.10 показывает, что метод POST должен сделать недействительным ресурс для кэширования.

6 голосов
/ 16 октября 2015

Если вы кешируете ответ POST, он должен быть в направлении веб-приложения. Это то, что подразумевается под "ответами на этот метод, которые нельзя кэшировать, если ответ не включает в себя соответствующие поля заголовка Cache-Control или Expires."

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

Следующие GET могут обслуживаться из кэша при этом предположении.

Приложение, которое не может прикрепить необходимые и правильные заголовки для проведения различий между кэшируемыми и не кэшируемыми ответами POST, является ошибочным для любых неверных результатов кэширования.

Тем не менее, каждый POST, который попадает в кэш, требует проверки с использованием условных заголовков. Это необходимо для обновления содержимого кэша, чтобы результаты POST не отражались в ответах на запросы до истечения срока жизни объекта.

4 голосов
/ 09 марта 2009

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

2 голосов
/ 07 июля 2014

Марк Ноттингем проанализировал, когда возможно кэшировать ответ POST. Обратите внимание, что последующие запросы, которые хотят использовать преимущества кэширования, должны быть запросами GET или HEAD. Смотри также httpbis

POST не имеют дело с представлениями идентифицированного состояния, 99 раз из 100. Однако есть один случай, когда это происходит; когда сервер выходит из его способ сказать, что этот ответ POST является представлением его URI, установив заголовок Content-Location, который совпадает с запросом URI. Когда это происходит, ответ POST похож на ответ GET к тому же URI; его можно кэшировать и использовать повторно - но только на будущее ПОЛУЧИТЬ запросы.

https://www.mnot.net/blog/2012/09/24/caching_POST.

1 голос
/ 09 марта 2009

Конечно, это возможно. Если вы хотите перехватывать POST-запросы, отправленные на ваш сервер, и кэшировать данные, отправленные обратно для повторной отправки позже - без проблем.

Сложная часть касается "состояния". Как вы решаете, что данные, которые вы хотите отправить обратно пользователю, должны быть одинаковыми? Что если его куки изменились - это изменит данные, которые вы хотите отправить обратно?

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

0 голосов
/ 19 мая 2014

С помощью firefox 27.0 и httpfox 19 мая 2014 года я увидел одну строчку этого: 00: 03: 58.777 0,488 657 (393) POST (кэш) текст / html https://users.jackiszhp.info/S4UP

Очевидно, что ответ метода post кэшируется, и он также находится в https. Невероятно!

0 голосов
/ 12 июня 2013

POST используется в Ajax с сохранением состояния. Возврат кэшированного ответа для POST разрушает канал связи и побочные эффекты при получении сообщения. Это очень, очень плохо. Это также настоящая боль, чтобы выследить. Настоятельно рекомендуется против.

Тривиальным примером может служить сообщение о том, что в качестве побочного эффекта выплачивается ваша зарплата в размере 10 000 долларов США на текущей неделе. Вы не хотите, чтобы получить «ОК, это прошло!» страница назад, которая была кеширована на прошлой неделе. Другие, более сложные случаи из реальной жизни приводят к аналогичной веселости.

...