我们的调查表明,并非所有浏览器都以统一的方式尊重HTTP缓存指令。

出于安全原因,我们不希望应用程序中的某些页面被web浏览器缓存。这必须至少适用于以下浏览器:

Internet Explorer 6+Firefox 1.5+Safari 3+歌剧9+铬

我们的要求来自安全测试。从我们的网站注销后,您可以按后退按钮并查看缓存的页面。


当前回答

此外,如果您使用.htaccess文件启用缓存,请确保重置该文件中的ExpiresDefault。

ExpiresDefault "access plus 0 seconds"

然后,可以使用ExpiresByType为要缓存的文件设置特定值:

ExpiresByType image/x-icon "access plus 3 month"

如果您的动态文件(如php等)被浏览器缓存,并且您无法找出原因,那么这可能也很有用。选中ExpiresDefault。

其他回答

当使用浏览器的后退按钮时,BalusC提供的答案中的标题不会阻止Safari 5(以及可能更旧的版本)显示浏览器缓存中的内容。防止这种情况的一种方法是在body标记中添加一个空onunload事件处理程序属性:

<body onunload=""> 

这个黑客显然破坏了Safari中的前向缓存:当单击后退按钮时,是否存在跨浏览器加载事件?

RFC for HTTP 1.1指出,正确的方法是为以下内容添加HTTP标头:

缓存控制:无缓存

如果较旧的浏览器不符合HTTP 1.1,它们可能会忽略这一点。对于那些你可以尝试标题:

Pragma:无缓存

这也适用于HTTP1.1浏览器。

我在<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()

(嘿,大家:请不要盲目地复制和粘贴所有你能找到的标题)

首先,后退按钮历史记录不是缓存:

新鲜度模型(第4.2节)不一定适用于历史机制。也就是说,历史机制可以显示以前的表示,即使它已经过期。

在旧的HTTP规范中,措辞更加强硬,明确告诉浏览器忽略后退按钮历史的缓存指令。

Back应该返回到时间(用户登录时的时间)。它不会导航到以前打开的URL。

然而,实际上,在非常特殊的情况下,缓存会影响后退按钮:

页面必须通过HTTPS传递,否则,这种缓存破坏将不可靠。此外,如果您没有使用HTTPS,那么您的页面很容易以其他方式被窃取登录信息。您必须发送缓存控制:无存储,必须重新验证(某些浏览器观察到无存储,有些浏览器观察到必须重新验证)

您永远不需要:

<meta>带有缓存头-它根本不起作用。完全没用。后检查/预检查-这是一个仅适用于可计算资源的IE指令。发送相同的标题两次或十几次。一些PHP片段实际上取代了以前的头,导致只发送最后一个。

如果需要,可以添加:

没有缓存或最大年龄=0,这将使资源(URL)“过时”,并要求浏览器与服务器检查是否有更新的版本(没有商店已经暗示了这一点)。对于HTTP/1.0客户端,过期日期为过去的日期(尽管现在真正的HTTP/1.0客户机完全不存在)。


好处:新的HTTP缓存RFC。

这些指令不会减轻任何安全风险。它们实际上是为了迫使UA更新不稳定的信息,而不是阻止UA保留信息。看到这个类似的问题。至少,不能保证任何路由器、代理等也不会忽略缓存指令。

更积极的是,有关计算机物理访问、软件安装等方面的政策将使您在安全方面领先于大多数公司。如果这些信息的消费者是公众,你唯一能做的就是帮助他们明白,一旦信息到达他们的机器,那台机器就是他们的责任,而不是你的责任。