Caching POST

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

One of the changes in Apple’s release of iOS6 last week was a surprising new ability to cache POST responses.

Lots has been said about this, but some people reading RFC2616 have come away scratching their head about whether this is actually a bug or not.

The HTTP spec says this about POST:

Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. Which, on the face of it, seems to say that a response to a POST can be cached.

In fact, that is true, but how you’re allowed to subsequently use it is another matter that (unfortunately) 2616 is pretty obtuse about getting across.

The first clue is here:

All methods that might be expected to cause modifications to the origin server’s resources MUST be written through to the origin server. This currently includes all methods except for GET and HEAD. A cache MUST NOT reply to such a request from a client before having transmitted the request to the inbound server, and having received a corresponding response from the inbound server. So, POST always has to be sent all the way to the origin server, no exceptions, even if you have a cache.

Second, the definition of POST hints that caching the response isn’t terribly useful in terms of reusing it for future requests, because:

The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. […] The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

Finally, if you try to cache a POST for reuse for future POSTs, you quickly realise that the request body needs to be part of the cache key – something that 2616’s caching section is completely silent about. That’s because, to the authors at the time, it was obvious that a HTTP cache can only be a GET cache – i.e., it can only store representations of the server’s state, and POSTs don’t deal in representations of identified state, 99 times out of 100.

However, there is one case where it does; when the server goes out of its way to say that this POST response is a representation of its URI, by setting a Content-Location header that’s the same as the request URI. When that happens, the POST response is just like a GET response to the same URI; it can be cached and reused – but only for future GET requests.

When we rewrote the caching section in HTTPbis (the revision to clarify HTTP/1.1 currently finishing up in the IETF, which I chair), we’ve ended up with a much more straightforward way to say it:

Responses to POST requests are only cacheable when they include explicit freshness information (see Section 4.1.1 of [Part6]). A cached POST response with a Content-Location header field (see Section 9.8) whose value is the effective Request URI MAY be used to satisfy subsequent GET and HEAD requests.

Note that POST caching is not widely implemented.

This is based upon the logic above, along with the recollections and insights of some of the folks who were there at the beginning, especially Roy Fielding, as well as cache implementers like Henrik Nordstr?m from Squid. So, POST caching is possible, but it’s only useful in a very narrow way – when you want to use the result of the POST to serve future GETs for the same URI. And, as the spec says, it’s not commonly implemented. See Subbu’s example and links to discussion at the time for more information.

Back to Apple: even without the benefit of this context, they’re still clearly violating the spec; the original permission to cache in 2616 was contingent upon there being explicit freshness information (basically, Expires or Cache-Control: max-age).

So, it’s a bug. Unfortunately, it’s one that will make people trust caches even less, which is bad for the Web. Hopefully, they’ll do a quick fix before developers feel they need to work around this for the next five years.

4 Comments

Jason Orendorff said:

The new wording is misleading too. Unless the reader already knows better, it still sounds like a cached response from a POST may be used to satisfy a subsequent POST.

If you want your readers to know that’s not allowed, you have to say it, and cross-reference to the section that spells it out: “A POST request can never be satisfied by a cached entry (see section xx.xx).”

Wednesday, September 26 2012 at 6:29 AM

Mark Nottingham said:

The Roy Fielding that lives in the back of my head screams “if we document all of the stupid things that people can do, we’ll never finish” and I generally agree.

However, I have made a small change - see http://trac.tools.ietf.org/wg/httpbis/trac/changeset/1913#file1

Thursday, September 27 2012 at 2:15 AM

julian-reschke.de said:

So, out of curiosity: did anybody actually submit a bug report to Apple? Was this fixed in 6.0.1???

Friday, November 2 2012 at 6:59 AM

时间: 2024-10-14 05:33:01

Caching POST的相关文章

Is Safari on iOS 6 caching $.ajax results? post Cache

https://stackoverflow.com/questions/12506897/is-safari-on-ios-6-caching-ajax-results Since the upgrade to iOS 6, we are seeing Safari's web view take the liberty of caching $.ajaxcalls. This is in the context of a PhoneGap application so it is using

[Architect] ABP(现代ASP.NET样板开发框架)(9) Caching

本节目录 介绍 ICacheManager WARNING: GetCache Method ICache ITypedCache Configuration 介绍 Abp提供了1个缓存的抽象.内部使用这个缓存抽象.虽然默认的实现使用MemoryCache,但是可以切换成其他的缓存. ICacheManager 提供缓存的接口为ICacheManager.我们可以注入并使用他.如: public class TestAppService : ApplicationService { privat

#Memcached系列#(6)使用Enyim.Caching访问Memcached的一个C#控制台程序

这篇文章主要是通过Enyim.Caching来完成访问Memcached. 这篇文章标为"原创",其实,是从多个地方整合过来的内容:但觉得"转载"也不合适,也并不是完全照搬别人的东西. 参考网址(不过,感觉它的配置写的乱糟糟的):http://www.cnblogs.com/luyinghuai/archive/2008/08/28/1278200.html (1)首先下载EnyimMemcached(文件名:EnyimMemcached-master.zip).

C#数据缓存介绍及Caching通用帮助类整理

C#缓存主要是为了提高数据的读取速度.因为服务器和应用客户端之间存在着流量的瓶颈,所以读取大容量数据时,使用缓存来直接为客户端服务,可以减少客户端与服务器端的数据交互,从而大大提高程序的性能. 以下为工作中经常用到的缓存操作公用类库整理: using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Ca

Phalcon之缓存对象关系映射(Caching in the ORM)

现实中的每个应用都不同,一些应用的模型数据经常改变而另一些模型的数据几乎不同.访问数据库在很多时候对我们应用的来说 是个瓶颈.这是由于我们每次访问应用时都会和数据库数据通信,和数据库进行通信的代价是很大的.因此在必要时我们可以通过增加 缓存层来获取更高的性能. 本章内容的重点即是探讨实施缓存来提高性能的可行性.Phalcon框架给我们提供了灵活的缓存技术来实现我们的应用缓存. 缓存结果集(Caching Resultsets)? 一个非常可行的方案是我们可以为那些不经常改变且经常访问的数据库数据

[Webpack 2] Hashing with Webpack for long term caching

Leveraging the browser cache is an important part of page load performance. A great way to utilize this cache is by versioning your resources. In this lesson, learn how to use Webpack’s hashing feature so you can take advantage of long term caching o

6.824 Lab 5: Caching Extents

Introduction In this lab you will modify YFS to cache extents, reducing the load on the extent server and improving YFS performance. The main challenge is to ensure consistency of extents cached at different yfs_clients: to make sure that each yfs_cl

Caching Bitmaps

由于要做网络图片的显示,所以先翻译了一下官网的文档,以作备用,  地址http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html. Loading a single bitmap into your user interface (UI) is straightforward, however things get more complicated if you need to load a large

[中英对照]Why Redis beats Memcached for caching | 在cache化方面,为何Redis胜过Memcached?

对Memcached和Redis有兴趣的同学不妨花几分钟读一读本文,否则请飘过. Why Redis beats Memcached for caching | 在cache化方面,为何Redis胜过Memcached? Memcached is sometimes more efficient, but Redis is almost always the better choice. XXX Memcached or Redis? It's a question that nearly al