ChatGPT解决这个技术问题 Extra ChatGPT

有没有办法强制浏览器刷新/下载图像?

我有一个问题,用户报告他们的图像没有被上传并且旧的图像仍然存在。仔细检查后,新图像就在那里,它们只是与旧图像具有相同的名称。我在上传时所做的是重命名图像以用于 SEO 目的。当他们删除图像时,旧索引变得可用并被重复使用。因此,它具有相同的图像名称。

有没有办法(我想可能有一个元标记)告诉浏览器不要使用它的cahce?

更好的答案是将图像重命名为全新的名称。我会着手解决这个问题,但与此同时,当我解决更大的问题时,这是一个快速的解决方案。

如果您想在缓存中更新而不是更改 URL:stackoverflow.com/a/70954519/11216915

i
isherwood

附加一个带有任意唯一编号(或时间、或版本号等)的查询字符串:

<img src="image.png?80172489074" alt="a cool image" />

由于 URL 不同,这将导致一个新的请求。


+1,但严格来说它不是不同的文件名;-) 文件名组件是相同的,但 URL 肯定是不同的。
Gubmo, unique 有点太多了,在这种情况下最好是添加文件的 mtime - 这样它只会在需要时重新加载。
最好的方法是使用发行版的版本号。
@hacker:随机性并不能保证两个生成的值可能不相同。但唯一性确实保证了两个生成的值不相同。并且该文件的修改日期不是该文件的唯一数据吗?
@RobertSinclair 是的。每个 URL 将被独立缓存。这就是为什么您可以附加文件修改时间、版本号或文件哈希以在底层文件更改时强制“浏览器刷新”的原因。
n
ndp

这很难。您确实希望缓存图像,但是一旦有新图像可用,您就不想缓存它们:

使用带有过去日期的 expires 标头可以防止任何缓存。坏的

添加“缓存破坏”参数 ?342038402 可以解决问题,但也可以防止图像被缓存,这不是您想要的。坏的。

使用短的(比如说 1 小时)expires 标头会更好......一个小时后,用户将看到图像,但您的网络服务器不必每次都提供它。妥协,但什么时间有效?实在不可行。

解决方案?我能想到两个不错的选择:

查看 eTag 以及您使用它们的能力。这些是针对这种情况设计的。浏览器将明确询问您的服务器文件是否是最新的。如果你没有它,你可以在 apache 中打开它。

为每个新图像创建一个新 URL(并使用远期过期标头)。这就是你正在做的事情。


“添加一个“缓存破坏”......不好。” 这不是真的,它会强制浏览器为图像缓存这个特定的版本,所以 image.png?342038402 将被缓存为那个版本。如果您有相同的图像和不同的查询字符串,那就不好了。
michaelmol,但是每次更改图像时您都必须手动创建一个新的随机数?我知道你不希望它永远缓存。使用这种技术,我看不到一种方法可以将图像上传到具有相同名称的位置,并以编程方式使用新的随机数更新路径
@ChadMizner 如果使用 PHP,您可以将 PHP 的 filemtime(string $filename) 函数与“缓存破坏”参数结合使用。这样,该文件的 URL 每次都会更改,请求的文件已更改。 (感谢 Michael Krelin - 黑客)。
是否更改附加到图像 url 的值并不重要。一旦最后有一些东西,你的浏览器将从服务器获得一个新的副本(即使那个值没有改变)。这就是为什么它很糟糕!
G
Gianluca Demarinis

我最喜欢的 PHP 解决方案:

<img src="<?php echo "image.jpg" . "?v=" . filemtime("image.jpg"); ?>" />

文件的每次更改“创建”文件的新版本


R
Rob Vanders

将当前日期时间附加到图像 src:

<img src="yourImage.png?v=<?php echo Date("Y.m.d.G.i.s")?>" />

您也可以关闭缓存,因为您的示例将强制浏览器每次下载文件(因为时间戳每秒都会更改)。我建议在最后删除 i 和 s,因此时间戳每小时都会更改。这样,浏览器每小时只会下载一次图像。 “YmdG”
s
samuil

您可以将 http-equiv 放在 <meta> 标记中,这将告诉浏览器不要使用缓存(甚至更好 - 以某种定义的方式使用它),但最好将服务器配置为发送正确的 http cache 标头。查看article on caching

尽管如此,一些浏览器可能不支持所有的 http 标准,但我相信这是要走的路。


相反,使用变通办法支持浏览器对这些想法的不良支持;)我明白你的意思,而且我知道进一步的讨论通常无济于事——有些东西“更好”但不能按预期工作,有些东西“更糟”但确实有效.这完全取决于 webdev,他/她会选择什么。
s
stackFan

去随机。只需使用一些随机数并将其附加图像文件名即可。

<img src="image.jpg?<?=rand(1,1000000)?>">

尝试使用文件的最后修改日期。因此只有在新文件被更改时才能下载新文件
G
Gianluca Demarinis

另一个强大的解决方案:

<img src="image.png?v=<?php echo filemtime("image.png"); ?>" />

这会在路径上打印“last-modification-timestamp”。

新版本 --> 下载新镜像

相同的版本 --> 取缓存的一个


R
RageZ

您可以通过使用 HTTP 标头来控制缓存行为。

过去设置 expires 标头将强制浏览器不使用缓存版本。

Expires: Sat, 26 Jul 1997 05:00:00 GMT

您可以查阅 RFC 了解更多详情。


RageZ 的问题是,您还必须让某些浏览器的开发人员查阅 RFC。
是的……但至少是相关文件。实施后故障有点...
我完全赞成正确实施,但我们必须面对现实。
大多数浏览器都正确实现了这一点,回到丑陋的 IE6 时代,但现在应该没问题。
如果浏览器从其 HTTP 缓存请求图像,它将不会(不应该)使用缓存版本。但是,如果浏览器有图像的内存副本,它有时会直接使用它而不查询其缓存。将唯一的片段标识符添加到图像 URL 以确保它不使用图像的内存副本。
A
Aaron Digulla

如果您查看浏览器和服务器之间交换的数据,您会看到浏览器将发送一个 HTTP HEAD 请求以获取图像。结果将包含修改时间(但不包含实际图像数据)。如果服务器上的图像发生更改并且浏览器应再次下载图像,请确保此时间更改。


取决于浏览器 - 一种较低延迟的技术是在 GET 请求中使用 If-Modified-Since 标头。结果还是一样——确保你正确地报告了文件的修改时间,这样缓存失效才能正常工作。
G
Gianluca Demarinis

在 PHP 中你可以使用这个技巧

<img src="image.png?<?php echo time(); ?>" />

time() 函数显示当前时间戳。每个页面加载都是不同的。所以这段代码欺骗了浏览器:它读取了另一个路径,并且它“认为”自从用户上次访问该站点以来图像发生了变化。它必须重新下载它,而不是使用缓存之一。


B
Ben Matheson

听起来更关心的是主要用户看到他们的新图像而不是缓存被完全禁用?如果是这种情况,您可以执行以下操作:

var headers = new Headers()
headers.append('pragma', 'no-cache')
headers.append('cache-control', 'no-cache')

var init = {
  method: 'GET',
  headers: headers,
  mode: 'no-cors',
  cache: 'no-cache',
}

fetch(new Request('path/to.file'), init)

如果您在上传新图像后执行此操作,浏览器应该会看到这些标头并调用后端,跳过缓存。新图像现在在该 URL 下的缓存中。主要用户将看到新图像,但您仍然保留缓存的所有好处。一旦他们的缓存失效,任何其他查看此图像的人都会在一天左右的时间内看到更新。

如果更关心的是确保所有用户都能看到最新版本,那么您可能希望使用其他解决方案之一。


A
Arvy

在 PHP 中,您可以发送一个随机数或当前时间戳:

<img src="image.jpg?<?=Date('U')?>">

或者

<img src="image.jpg?<?=rand(1,32000)?>">

t
tijntest

结果不好,我认为这是正确编程的方法。

 <td><?php echo "<img heigth=90 width=260 border=1 vspace=2 hspace=2 src=".$row['address']."?=".rand(1,999)."/>" ?></td>

M
Manish Meshram

前段时间我就提出过这个问题。我正在通过 AJAX 中的 JSON 获取数据。所以我所做的是,我只是添加了一个 Math.random() Javascript 函数,它就像一个魅力。我使用的后端是一个烧瓶。