After a little astonishment of all the shooting in the dark in this topic, here's my contribution:
The correct minimum set which works in all of the mentioned browsers is the following:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
The PHP way would look like:
header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1.
header('Pragma: no-cache'); // HTTP 1.0.
header('Expires: 0'); // Proxies.
The Java/Servlet way would look like:
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
The ASP.NET way would look like:
Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
Response.AppendHeader("Expires", "0"); // Proxies.
The Cache-Control
is per the HTTP 1.1 spec for clients (and implicitly required by some browsers next to Expires
), the Pragma
is per the HTTP 1.0 spec for clients and proxies and Expires
is per the HTTP 1.1 spec for clients and proxies.
Other Cache-Control
parameters are irrelevant if the abovementioned three are specified. The Last-Modified
header is only intersting if you actually want to cache the request.
Note that when you include the headers both programmatically and inside the HTML page as <meta>
tags, then the ones which are programmatically specified will get precedence above the ones on the same field in the HTML <meta>
tags, because they appears directly in the response headers instead of the response body.