如何强制Chrome不缓存重定向?

7
一个简单的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

问题:在 Chrome (最新的 win/mac 版本) 返回和前进到这个 HTML 页面时,不重新验证地址 http://someaddr/image.php
我尝试了使用 302 和 303 重定向(RFC 中 303 要求浏览器绝不能缓存),在 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}">

但我不喜欢/不能使用那样的hack。还有其他选项吗?

你尝试过使用 Expires: -1 吗?同时在 pragma 中添加 no-store - aldo.roman.nurena
过期时间:-1,在Chrome上无效。 - thedk
我进一步调查了Chrome。我在页面上制作了一个JavaScript,动态地将<img>插入到页面内容中。即使在这种情况下,Chrome仍然拒绝连接到源src URL。 - thedk
似乎使用no-store而不是no-cache可以解决问题。 你可以看一下这个链接:https://dev59.com/nm855IYBdhLWcg3wyniC - aldo.roman.nurena
我尝试了不同的组合,包括单独使用“no-store”,同时使用“no-store”和“no-cache”,但似乎都没有起效。 - thedk
@thedk,你在这方面有什么进展了吗?根据此错误报告上的评论者所说,“似乎Chrome将第二个(重定向)请求的响应缓存到初始请求的值中,而不是像2个独立的HTTP请求一样正确地缓存它们。”因此,也许这就是防止缓存的关键。 - Myrne Stol
2个回答

5
尝试使用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 )

1
从页面内部使用window.location,例如,随机的get请求是对我有效的。我创建了一个类似GUID的随机字符串并将其附加为get请求。而且你真正需要的只是x,即example.com?x,其中x是一个随机键值。 - ps2goat
另外需要注意:尽量不要使用服务器脚本可能使用的任何内容,否则可能会得到冲突的结果... 为了安全起见,您可以只输入一堆乱码(例如example.com?kjsdjksdjhkds) - JxAxMxIxN

-3

从另一个问题中发布的链接

 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的ETags和最后修改日期来确保您不会发送浏览器已经缓存的数据。

$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的问题。 - thedk
嗯...我的错,看起来你已经说过它可以在其他浏览器上运行了。 - awm
但是你提到添加一个随机数可以解决问题;这意味着chrom正在向服务器发送请求。你如何解释这个? - awm
当我导航回该页面时,Chrome会从服务器下载它,但以某种神秘的方式,它从未寻找过http://someaddr/image.php。它表现得好像另有一个链接(http://someaddr/random_image_12345.jpg)被放在 <img src=...> 中,因为连接日志只显示它试图获取http://someaddr/random_image_12345.jpg(已缓存)。 - thedk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接