2009-03-09 4 views

ответ

72

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

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

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

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

- PUT 
    - DELETE 
    - POST 

Это мне не ясно, каким образом эти характеристики могут позволить значимого кэширования.

+1

Этот раздел относится к промежуточному кешу (например, кэш-прокси-серверу), а не к исходному серверу. –

+0

Верно, но их можно интерпретировать и в этом контексте (и они имеют смысл). –

+2

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

2

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

Незначительная часть приходит в отношении «состояния». Как вы решаете, данные, которые вы хотите отправить обратно пользователю, должны быть одинаковыми? Что делать, если его файлы cookie изменились - это изменит данные, которые вы хотите отправить обратно?

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

+1

+1 хорошо обоснованный ;-) –

+1

Возможно, да. Нарушение RFC 2616 (HTTP/1.1) также очень вероятно. Ломать/не работать в браузерах, ожидающих HTTP/1.1, возможно. Выбирайте. – Piskvor

4

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

+0

Запрос POST может не изменять какие-либо данные, которые используются для создания страницы ответов, и в этом случае имеет смысл кэшировать ответ. –

+0

David Z: Конечно, если POST меняет данные, тогда ответ должен дать некоторые указания на успех/неудачу. Не требуется точно, но я не могу придумать ситуацию, когда POST изменит данные, а ответ будет статичным. – Morvael

+2

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

31

Всего:

В основном POST is not an idempotent operation. Поэтому вы не можете использовать его для кеширования. GET должна быть идемпотентной, поэтому она обычно используется для кэширования.

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

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

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

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

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

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

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

Что касается кэширования прокси:

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

Что касается кэширования сервера:

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

утратившей сила ресурса:

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

+2

«В принципе POST не является идемпотентной операцией, поэтому вы не можете использовать его для кеширования». Это просто неправильно, и на самом деле это не имеет смысла, см. Ответ reBoot для деталей. К сожалению, я пока не могу понизить, иначе я бы это сделал. –

+1

Eugene: Я изменил «не» на «не может». –

+1

Спасибо Брайан, это звучит лучше. Моя проблема с вашим «POST not idemp. -> не может быть кэширована», хотя была - и я не делал этого достаточно ясно, даже если операция не является идемпотентной, что не означает, что она не кэшируема. Я думаю, вопрос в том, что вы смотрите на него с точки зрения сервера, который предлагает данные и знает его семантику, или вы смотрите на него со стороны приема (будь то кэширующий прокси и т. Д. Или клиент) , Если это клиент/proxy pov, я полностью согласен с вашим сообщением. Если это серверный pov, если сервер говорит: «клиент может кэшировать», чем клиент может кэшировать. –

55

В соответствии с RFC 2616 Раздел 9.5:

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

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

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

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

+2

+1 reBoot, спасибо за объяснение проблемы с заголовками, а также исправление ошибочных заявлений относительно 13.10. Удивительно, что эти неправильные ответы получили так много голосов. –

+2

В чем разница между «аннулировать ресурс для кеширования» и «сделать кешированную версию URI устаревшей»? Вы говорите, что серверу разрешено кэшировать ответ POST, но клиенты могут этого не делать? – Gili

-1

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

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

+0

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

0

С светлячок 27,0 & с HTTPFox, 19 мая 2014 года, я увидел одну строчку этого: 00: 03: 58,777 0,488 657 (393) POST (Cache) текст/html https://users.jackiszhp.info/S4UP

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

2

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

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

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

4

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

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

В соответствии с этим допущением можно использовать кеширование из кеша.

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

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

Смежные вопросы