我们的调查表明,并非所有浏览器都以统一的方式尊重HTTP缓存指令。
出于安全原因,我们不希望应用程序中的某些页面被web浏览器缓存。这必须至少适用于以下浏览器:
Internet Explorer 6+Firefox 1.5+Safari 3+歌剧9+铬
我们的要求来自安全测试。从我们的网站注销后,您可以按后退按钮并查看缓存的页面。
我们的调查表明,并非所有浏览器都以统一的方式尊重HTTP缓存指令。
出于安全原因,我们不希望应用程序中的某些页面被web浏览器缓存。这必须至少适用于以下浏览器:
Internet Explorer 6+Firefox 1.5+Safari 3+歌剧9+铬
我们的要求来自安全测试。从我们的网站注销后,您可以按后退按钮并查看缓存的页面。
当前回答
免责声明:我强烈建议阅读@BalusC的答案。阅读以下缓存教程后:http://www.mnot.net/cache_docs/(我建议你也读一下),我相信这是正确的。然而,出于历史原因(并且因为我自己测试过),我将在下面附上我的原始答案:
我尝试了PHP的“接受”答案,但这对我来说不起作用。然后我做了一些研究,发现了一个轻微的变体,对其进行了测试,结果成功了。这里是:
header('Cache-Control: no-store, private, no-cache, must-revalidate'); // HTTP/1.1
header('Cache-Control: pre-check=0, post-check=0, max-age=0, max-stale = 0', false); // HTTP/1.1
header('Pragma: public');
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Expires: 0', false);
header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
header ('Pragma: no-cache');
这应该奏效。问题是,当两次设置头的相同部分时,如果没有将false作为第二个参数发送给头函数,头函数将简单地覆盖前面的header()调用。因此,在设置缓存控件时,例如,如果不想将所有参数放在一个header()函数调用中,则必须执行以下操作:
header('Cache-Control: this');
header('Cache-Control: and, this', false);
请在此处查看更完整的文档。
其他回答
对于ASP.NET Core,创建一个简单的中间件类:
public class NoCacheMiddleware
{
private readonly RequestDelegate m_next;
public NoCacheMiddleware( RequestDelegate next )
{
m_next = next;
}
public async Task Invoke( HttpContext httpContext )
{
httpContext.Response.OnStarting( ( state ) =>
{
// ref: http://stackoverflow.com/questions/49547/making-sure-a-web-page-is-not-cached-across-all-browsers
httpContext.Response.Headers.Append( "Cache-Control", "no-cache, no-store, must-revalidate" );
httpContext.Response.Headers.Append( "Pragma", "no-cache" );
httpContext.Response.Headers.Append( "Expires", "0" );
return Task.FromResult( 0 );
}, null );
await m_next.Invoke( httpContext );
}
}
然后在Startup.cs中注册
app.UseMiddleware<NoCacheMiddleware>();
确保在以下位置添加此
app.UseStaticFiles();
此外,如果您使用.htaccess文件启用缓存,请确保重置该文件中的ExpiresDefault。
ExpiresDefault "access plus 0 seconds"
然后,可以使用ExpiresByType为要缓存的文件设置特定值:
ExpiresByType image/x-icon "access plus 3 month"
如果您的动态文件(如php等)被浏览器缓存,并且您无法找出原因,那么这可能也很有用。选中ExpiresDefault。
(嘿,大家:请不要盲目地复制和粘贴所有你能找到的标题)
首先,后退按钮历史记录不是缓存:
新鲜度模型(第4.2节)不一定适用于历史机制。也就是说,历史机制可以显示以前的表示,即使它已经过期。
在旧的HTTP规范中,措辞更加强硬,明确告诉浏览器忽略后退按钮历史的缓存指令。
Back应该返回到时间(用户登录时的时间)。它不会导航到以前打开的URL。
然而,实际上,在非常特殊的情况下,缓存会影响后退按钮:
页面必须通过HTTPS传递,否则,这种缓存破坏将不可靠。此外,如果您没有使用HTTPS,那么您的页面很容易以其他方式被窃取登录信息。您必须发送缓存控制:无存储,必须重新验证(某些浏览器观察到无存储,有些浏览器观察到必须重新验证)
您永远不需要:
<meta>带有缓存头-它根本不起作用。完全没用。后检查/预检查-这是一个仅适用于可计算资源的IE指令。发送相同的标题两次或十几次。一些PHP片段实际上取代了以前的头,导致只发送最后一个。
如果需要,可以添加:
没有缓存或最大年龄=0,这将使资源(URL)“过时”,并要求浏览器与服务器检查是否有更新的版本(没有商店已经暗示了这一点)。对于HTTP/1.0客户端,过期日期为过去的日期(尽管现在真正的HTTP/1.0客户机完全不存在)。
好处:新的HTTP缓存RFC。
我在<head><meta>元素方面运气不佳。直接(在HTML文档之外)添加与HTTP缓存相关的参数确实对我有用。
Python中使用web.py-web.header调用的示例代码如下。我有目的地编辑了我个人无关的实用程序代码。
import web import sys import PERSONAL-UTILITIES myname = "main.py" urls = ( '/', 'main_class' ) main = web.application(urls, globals()) render = web.template.render("templates/", base="layout", cache=False) class main_class(object): def GET(self): web.header("Cache-control","no-cache, no-store, must-revalidate") web.header("Pragma", "no-cache") web.header("Expires", "0") return render.main_form() def POST(self): msg = "POSTed:" form = web.input(function = None) web.header("Cache-control","no-cache, no-store, must-revalidate") web.header("Pragma", "no-cache") web.header("Expires", "0") return render.index_laid_out(greeting = msg + form.function) if __name__ == "__main__": nargs = len(sys.argv) # Ensure that there are enough arguments after python program name if nargs != 2: LOG-AND-DIE("%s: Command line error, nargs=%s, should be 2", myname, nargs) # Make sure that the TCP port number is numeric try: tcp_port = int(sys.argv[1]) except Exception as e: LOG-AND-DIE ("%s: tcp_port = int(%s) failed (not an integer)", myname, sys.argv[1]) # All is well! JUST-LOG("%s: Running on port %d", myname, tcp_port) web.httpserver.runsimple(main.wsgifunc(), ("localhost", tcp_port)) main.run()
将修改后的http头设置为1995年的某个日期通常会起作用。
下面是一个示例:
Expires: Wed, 15 Nov 1995 04:58:08 GMT Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT Cache-Control: no-cache, must-revalidate