To me this problem reads "I was doing something wrong, but it has worked, it should keep on working". In this case, if there has always been a working proper way, I think that it is OK to break the bad behaviour and force people to use the proper one.
As other have pointed out, the spec says: "POST responses should not be cached, unless you use a Cache-Control header. In that case do whatever Cache-Control says."
Now, "Cache-Control: max-age=0" may have been working fine up to now, but what its meaning is "this content is cacheable; please retain it only for 0 second". The first part of the sentence explicitly says that the content is cacheable, the second part is used by the browser as part of its cache policy. Please note that you _explicitly_ declared the content as cacheable. Do you want to _explicitly_ declare your content as not cacheable? Use "Content-Control: no-cache". Or just do not set Cache-Control and rely on the default non-cacheable status of POST responses.
The only problem here is that Safari is caching POST responses that have no Cache-Control header set. Yes that is a bug. But one cannot complain about the fact that a browser cached a response that has explicitly been said by its producer to be cacheable.
> Please note that you _explicitly_ declared the content as cacheable.
You also declared that it instantly becomes stale, so the browser must revalidate the entry before returning it. Safari returning a resource with Cache-Control: max-age=0 without contacting the server beforehand is an incorrect behavior, goes against the spec and is not defensible.
> But one cannot complain about the fact that a browser cached a response that has explicitly been said by its producer to be cacheable.
> A cache MAY be configured to return stale responses without validation, but only if this does not conflict with any "MUST"-level requirements concerning cache validation (e.g., a "must-revalidate" cache-control directive).
> Because a cache MAY be configured to ignore a server's specified expiration time, and because a client request MAY include a max-stale directive (which has a similar effect), the protocol also includes a mechanism for the origin server to require revalidation of a cache entry on any subsequent use.
Additionally, I will point out that the "cache: false" that people are discussing does not seem to be documented as part of the XHR interface; it is only something jQuery manipulates, and it seems to do nothing very useful with it: all it means is "if this is a GET/HEAD request, append a query-string with a millisecond-accurate timestamp"; it does nothing for POST requests, and it does not add any cache control headers to the request that could be used to indicate to either the browser or to upstream proxies that the content should not be returned from a cache.
To me this problem reads "I was doing something wrong, but it has worked, it should keep on working". In this case, if there has always been a working proper way, I think that it is OK to break the bad behaviour and force people to use the proper one.
As other have pointed out, the spec says: "POST responses should not be cached, unless you use a Cache-Control header. In that case do whatever Cache-Control says."
Now, "Cache-Control: max-age=0" may have been working fine up to now, but what its meaning is "this content is cacheable; please retain it only for 0 second". The first part of the sentence explicitly says that the content is cacheable, the second part is used by the browser as part of its cache policy. Please note that you _explicitly_ declared the content as cacheable. Do you want to _explicitly_ declare your content as not cacheable? Use "Content-Control: no-cache". Or just do not set Cache-Control and rely on the default non-cacheable status of POST responses.
The only problem here is that Safari is caching POST responses that have no Cache-Control header set. Yes that is a bug. But one cannot complain about the fact that a browser cached a response that has explicitly been said by its producer to be cacheable.