2010-05-19 98 views
4

我试图让Opera每次重新请求一个页面,而不是从缓存中提供它。我发送'Cache-control:no-cache'和'Pragma:no-cache'响应头文件,但似乎Opera只是忽略了这些头文件。它可以在其他浏览器中正常运行 - Chrome,IE,Firefox。如何停止Opera缓存页面?

如何从缓存页面停止Opera?我希望能够做的是当用户点击浏览器上的返回按钮时,Opera重新请求一个页面。

回答

7

作为一个用户,我绝对厌恶那些在使用后退按钮时通过强制重新加载减慢我的历史导航的页面。 (如果您每天使用的浏览器注意到各种缓存指令并让它们以您想要的开发方式影响历史导航,您可能会注意到一些网站会减慢自己的速度......)

如果你有一个非常强大的用例来做这件事我想说你的架构在某种意义上可能是“错误的”,例如,如果你在不断更新数据的不同“视图”之间切换,并且因此想要在执行时重新加载用户回去或许使用Ajaxy技术将不断变化的数据加载到当前页面会更好?

Opera的实现是有目的的 - “缓存”与“历史导航”在概念上有所不同,前者更多的是将内容存储在磁盘和会话之间,后者将切换回刚刚访问的临时隐藏页面,在你离开它的状态下。

但是,如果你确实需要它,那么这个政策中就有一个漏洞,使得你想要的行为成为可能。发送“缓存控制:必须重新验证”将强制Opera在导航上重新加载每一页,但如果您通过https发送页面,则仅限。 (这是偏执银行所要求的功能,如果应用于http,它会减慢太多正常站点的速度)。

+3

“这是一项针对偏执银行所要求的功能,如果应用于http,它会减慢太多正常站点的速度” 您是否认为浏览器不应该被真正用于可能有敏感数据的应用程序? :-) – 2010-05-20 14:33:37

+2

如果数据真的很敏感,网站应该使用https。 :-) 由于没有服务器和浏览器共享“会话”的概念,因此网络规范中存在一个漏洞。如果服务器可以告诉浏览器“用户刚刚注销/超时,并且我们关闭了会话,请禁止使用后退按钮查看自会话开始以来的历史记录”,我们可以在可用性和安全性之间找到更好的平衡。 – hallvors 2010-05-21 07:34:11

+2

我同意以下两点:(i)网络规范中有一个关于“共享会话状态”的漏洞,(ii)https应该用于真正敏感。但是,“真正的敏感数据”表明数据安全不是数字化的,而是一种模拟的措施。其他浏览器通过不允许缓存和必须重新验证工作来支持这一点,这允许进一步的范围来管理安全/隐私。 Opera不支持这个 - 对或错,我不担心。我需要一个解决方案来解决这种不一致问题。你在歌剧院工作,你能建议什么? (即脚本,标题等)Thks – Forer 2010-05-21 10:35:53

2

这听起来像你的问题是关于this answer。在测试您的头文件和建议的头文件后,我只能在Internet Explorer中重现您的预期行为。

+1

我反复在Opera上重现这个问题。它似乎是唯一不一致的浏览器。我已经阅读了他们严格,有原则的处理缓存的方法。但是这实际上只是看起来像一个安全漏洞,没有做额外的腿部工作。我真的很喜欢一个明确的解决方案,可以实施尼什卡尔的问题。在其他浏览器中,头缓存控件响应头不能在opera中工作。什么是工作? – Forer 2010-05-20 14:30:25

0

在搜索解决方案时发现此问题。没有喜悦,所以写了一些JavaScript来解决可能被其他人使用的问题。

<HEAD>上述任何其他JavaScript:

<script> 
    if(typeof(opera) != 'undefined') { // only do for Opera 
     if (window.name == 'previously_loaded') { // will be "" before page is loaded 
      alert('Reloading Page from Server'); // for testing 
      window.name = ''; // prevent multiple reload 
      window.location.reload(true); 
     } 
    } 
</script> 

现在改变窗口的名称,以便歌剧检测到它在随后进行的装载缓存:

window.name = 'previously_loaded'; 

插入这条线在你的js块的一个习惯在“窗口加载”期间执行,导致无限重新加载。对于我来说,除非有人通过链接退出,否则不需要刷新页面,所以我只是将它添加到我的onclick/onunload函数中。

Before and after demos这里还有一些笔记。我打算将其添加到我的博客。我只有Opera的几个迟到版本,所以我希望在演示之前对演示进行一些尝试,然后再将鸡蛋放在我的脸上。

编辑:刚刚意识到,如果稍后访问的网站更改窗口名称(它的持久性),那么背面的标签重新加载不会发生。只需更改以上陈述即可:

if (window.name != "") { 

在多个选项卡中打开时,Demo工作正常;但我隐约记得窗口名称应该是唯一的;所以我改变了演示来生成一个独特的名字。

window.name = new Date().getTime(); 
2

SIMPLE服务器侧高速缓存控制,无需标题或FRONTEND SCRIPTS

零依赖,通用语言版


您可以在全球范围强制重新缓存,而不使用头通过附加一个md5或sha1校验和到你的文件名。

这样它会缓存,如果它是一个完全匹配,否则对待它像一个新的资源。

  • 作品在所有浏览器
  • 确认出现严格的HTML5 (原来没有,但是这已经更新。未经检验的XHTML,但可能并不适用于该)
  • 不需要额外的头
  • 保持前端问题和后端问题很好地解耦。
  • 不需要客户端完整性检查或源验证。
  • 凡是可以打印HTML能做到这一点一致,包括静态内容
  • 如果不是静态的,易于扩展的运行时间控制到终端用户(身份验证,如果需要的话),允许简单的页面标志,以确定精缩,美化或调试源被返回。
  • 将内容服务机制中的客户端缓存控件完全封装起来,这使得维护起来非常简单。
  • 作为一个方面额外能力,引入了版本客户端缓存自动推迟到浏览器已经高速缓存了校验和,如果有替换版本,需要单元测试发布包,以确定它的最小稳定其可以是有用依赖版本什么的。

  • 你不要永远不得不摆弄你的浏览器来缓存不要再干扰你的开发过程。

  • 这种方法也可用于版本化的图像,视频,音频,pdf等。几乎任何作为静态数据提供服务的资源都将以类似的方式运行,缓存第一次请求内容,并自动保留进一步考虑文件是否改变。


这是RFC有效的标记。注意脚本和链接标签有一个GET字符串:

?checksum=ba411cafee2f0f702572369da0b765e2

<!doctype html> 

<html lang="en"> 
<head> 
    <meta charset="utf-8"> 

    <title>Client Cache Control Example</title> 
    <meta name="description" content="You're only going to cache this when the content changes, and always when the content changes."> 
    <meta name="author" content="https://stackoverflow.com/users/1288121/mopsyd"> 

    <!-- Example Stylesheet --> 
    <link rel="stylesheet" href="css/styles.css?checksum=ba411cafee2f0f702572369da0b765e2"> 

    <!-- Example Script --> 
    <script src="js/scripts.js?checksum=ba411cafee2f0f702572369da0b765e2"></script> 
</head> 
<body> 
</body> 
</html> 

的GET字符串?checksum=ba411cafee2f0f702572369da0b765e2指的是资源的文件大小的MD5或SHA1哈希值。它可以通过命令行,语言结构或通过将其从Content-Length:标头的值中散列化来获得。然后通过将其作为GET字符串附加到文件名来构造您的hrefsrc属性。

这个浏览器会将它们解释为独立的,并单独缓存。

如果服务器是静态资源,服务器将忽略GET参数,但如果它是动态服务的,那么GET参数将可供解释语言使用。

这意味着只要在链接,哈希值发生变化,浏览器会缓存特定版本独立一次,然后保存,直到永远,或Expires:的推移,以先到者为准。

由于校验和是文件大小的直接反映,因此您可以将Expires:设置为永久性,并且没有太大区别。只要该文件更改了一个字节,您仍然会立即看到您的更改。

  • 用你平时做的任何工具生成你的css或js源代码。

  • 在运行时上文件大小运行一个MD5或SHA1校验如果是动态服务,并在编译时如果要生成的静态内容(如ApiGen文档,例如)

  • 服务与哈希正常文件附加到文件名的GET字符串(例如:styles.css成为styles.css?checksum=ba411cafee2f0f702572369da0b765e2

  • 文件中的任何改变强制重新缓存,这意味着你看到真正的价值立即反映出来。

  • 可选,但RAD:这种方式的另外一个好处是,你可以很容易地建立一个开发GET标志,它将使所有前端源决心美化开发源启用任何自定义的调试功能,或者用它来解释版本控制标志。您可以执行冗余检查以确保该标志只从服务器的已知开发IP地址,代理身份验证等传递,否则,如果您需要安全标志,则不会执行该标志。我平时只要有可能与此类似分我的前端源达:

    • 这是它在做什么活,现在(精缩生产,缓存,默认情况下,?checksum=ba411cafee2f0f702572369da0b765e2)。
    • 这就是现在它应该做的事情,已经足够美化以供我阅读(美化产品,never cached,?debug_pretty_source=true)。
    • 这是我用弄清楚什么是没有做它应该活到如果在这两个先前的存在(美化启用调试,never cached,ACL /白名单授权,?debug_dev_enable=true或类似)。

可以采用同样的原则使用的版本号,而不是校验打包发布,提供你的版本不会改变。校验和的可读性较差,但易于自动化并与确切的更改保持同步,但版本后缀对测试程序包稳定性也很有用,前提是版本号反映了不可变的资源。

+0

应该注意的是,http转接代理有时会使用'GET'来干扰这种情况,这取决于请求到服务器的特定网络路径。在这种情况下,可以通过将散列直接附加到文件名而不是使用get字符串,然后使用'.htaccess'重写规则去除它们,即使在代理干扰的情况下也能工作。这通常不是问题,但有时可能会出现在某些边缘情况下。例如:'styles.ba411cafee2f0f702572369da0b765e2.css'而不是'styles.css?checksum = ba411cafee2f0f702572369da0b765e2' – mopsyd 2017-11-11 20:42:07