【问题标题】:How to force Chrome NOT to cache redirects?如何强制 Chrome 不缓存重定向?
【发布时间】:2012-11-13 06:07:30
【问题描述】:

一个简单的 HTML 代码:

<img src="http://someaddr/image.php">

image.php 是一个脚本,它返回一个随机重定向到具有所有必要的无缓存标头的静态图像:

Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Location: http://someaddr/random_image_12345.jpg

问题:来回导航到此 HTML 页面时,Chrome(最新 win/mac)不会重新验证地址 http://someaddr/image.php

我尝试过使用重定向 302 和 303(在 RFC 中有更严格的要求,即它不应该被浏览器缓存)。这就像 IE、FireFox、Opera 中的魅力一样。他们总是刷新http://someaddr/image.php。但 Chrome 没有。

我什至在 Chrome 中使用过开发者工具,而且似乎在网络日志中它甚至没有显示任何获取 http://someaddr/image.php 的尝试(缓存与否)。网络日志仅显示一个与http://someaddr/random_image_12345.jpg 的连接(缓存)。怎么这么破……

我知道将查询字符串放入图像源的天真/简单的解决方案:

    <img src="http://someaddr/image.php?refresh={any random number or timestamp}">

但我不喜欢/不能使用这样的技巧。还有其他选择吗?

【问题讨论】:

  • 你试过Expires: -1 吗?还要将no-store 添加到编译指示
  • 过期:-1,对 Chrome 没有影响。
  • 我对 chrome 的研究更加深入。我在页面上制作了一个 JavaScript,它动态地将 插入到页面内容中。即使在这种情况下,Chrome 也拒绝连接到源 src URL。
  • 似乎no-store 而不是no-cache 可以解决问题。你看看这个:stackoverflow.com/questions/4146813/…
  • 我尝试了单个“no-store”、“no-store”和“no-cache”的不同组合。似乎没有任何效果。

标签: google-chrome caching redirect


【解决方案1】:

来自link 发布在另一个问题中:

 The first header Cache-Control: must-revalidate means that browser must send validation request every time even if there is already cache entry exists for this object.
Browser receives the content and stores it in the cache along with the last modified value.
Next time browser will send additional header:
If-Modified-Since: 15 Sep 2008 17:43:00 GMT

This header means that browser has cache entry that was last changed 17:43.
Then server will compare the time with last modified time of actual content and if it was changed server will send the whole updated object along with new Last-Modified value.

If there were no changes since the previous request then there will be short empty-body answer:
HTTP/1.x 304 Not Modified

您可以使用 HTTP 的 etag 和上次修改日期来确保您不会发送已经缓存的浏览器数据。

$last_modified_time = filemtime($file); 
$etag = md5_file($file); 

header("Last-Modified: ".gmdate("D, d M Y H:i:s", $last_modified_time)." GMT"); 
header("Etag: $etag"); 

if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $last_modified_time || 
    trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag) { 
    header("HTTP/1.1 304 Not Modified"); 
    exit; 
} 

【讨论】:

  • 这个答案与问题无关。问题是 Chrome 甚至没有尝试连接到服务器。不是服务器缓存和返回304的问题。
  • 嗯......我的错,当你说它适用于其他浏览器时,看起来你已经说得很清楚了。
  • 但是您提到添加随机数有效;这意味着 chrom 正在向服务器发送请求。你怎么解释?
  • 当我导航回页面时,chrome 从服务器下载它,但以某种神秘的方式,他从不寻找someaddr/image.php。他的行为就像在 中放入了另一个链接 (someaddr/random_image_12345.jpg),因为连接日志仅显示他试图获取 someaddr/random_image_12345.jpg(缓存)。
【解决方案2】:

尝试 307 重定向

但是,如果您在尝试访问因缓存重定向而无法访问的链接时遇到困难...

这不会清除缓存,但如果您费尽心思试图访问已重定向缓存的链接,这是一种快速且可行的绕过方法。

将链接地址复制到地址栏中,并在地址中添加一些GET信息。

示例 如果您的网站是http://example.com

Put a ?x=y at the end of it 
( example.com?x=y ) - the x and y could be anything you want.

如果已经有 ?在 url 后面有一些信息

( example.com?this=that&true=t ) - try to add &x=y to the end of it...

( example.com?this=that&true=t&x=y )

【讨论】:

  • 从页面内部,例如使用window.location,随机获取请求对我来说是有效的。我创建了一个类似 GUID 的随机字符串并将其作为 get 附加。而 x 就是你真正需要的,即example.com?x,其中 x 是一个随机键值。
  • 还要注意:尽量不要使用您的服务器脚本可能使用的任何东西,否则您可能会得到相互冲突的结果...为了安全起见,您可以输入一堆乱码(example.com?kjsdjksdjhkds)
猜你喜欢
  • 2018-05-06
  • 2018-04-09
  • 2017-05-19
  • 2014-04-25
  • 2014-06-17
  • 1970-01-01
  • 1970-01-01
  • 2015-03-25
相关资源
最近更新 更多