我正在访问我的网站上的一个链接,每次访问它都会提供一个新的图像。

我遇到的问题是,如果我试图在后台加载图像,然后更新页面上的图像,图像不会改变——尽管在我重新加载页面时它会更新。

var newImage = new Image();
newImage.src = "http://localhost/image.jpg";

function updateImage()
{
if(newImage.complete) {
    document.getElementById("theText").src = newImage.src;
    newImage = new Image();
    number++;
    newImage.src = "http://localhost/image/id/image.jpg?time=" + new Date();
}

    setTimeout(updateImage, 1000);
}

FireFox看到的头文件:

HTTP/1.x 200 OK
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: image/jpeg
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Server: Microsoft-HTTPAPI/1.0
Date: Thu, 02 Jul 2009 23:06:04 GMT

我需要强制刷新页面上的图像。什么好主意吗?


当前回答

简单的解决方案:在响应中添加以下报头:

Cache-control: no-store

为什么这样做是清楚地解释在这个权威的页面:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control

这也解释了为什么无缓存不能工作。

其他答案并不适用,因为:

cache .delete是关于您可以为脱机工作创建的新缓存,请参阅:https://web.dev/cache-api-quick-guide/

在URL中使用#的片段不起作用,因为#告诉浏览器不要向服务器发送请求。

一个随机添加到url的缓存破坏者可以工作,但也会填满浏览器缓存。在我的应用程序中,我想每隔几秒钟从网络摄像头下载一张5mb的图片。完全冻结你的电脑只需要一个小时或更少的时间。我仍然不知道为什么浏览器缓存不限制在一个合理的最大值,但这绝对是一个缺点。

其他回答

我通过servlet将数据发送回来解决了这个问题。

response.setContentType("image/png");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.setDateHeader("Expires", 0);

BufferedImage img = ImageIO.read(new File(imageFileName));

ImageIO.write(img, "png", response.getOutputStream());

然后从页面中给它一个带有一些参数的servlet,以获取正确的图像文件。

<img src="YourServlet?imageFileName=imageNum1">

尝试在url的末尾添加cachebreaker:

newImage.src = "http://localhost/image.jpg?" + new Date().getTime();

这将在创建图像时自动附加当前时间戳,并且它将使浏览器重新查找图像,而不是从缓存中检索图像。

作为……的替代方案。

newImage.src = "http://localhost/image.jpg?" + new Date().getTime();

...看来……

newImage.src = "http://localhost/image.jpg#" + new Date().getTime();

...足以欺骗浏览器缓存而不绕过任何上游缓存,假设您返回了正确的cache - control头。虽然你可以用…

Cache-Control: no-cache, must-revalidate

...你就失去了If-Modified-Since或If-None-Match标头的好处,所以…

Cache-Control: max-age=0, must-revalidate

...应该防止浏览器重新下载整个图像,如果它实际上没有改变。在IE, Firefox和Chrome上进行测试和工作。令人恼火的是,它在Safari上失败了,除非你使用…

Cache-Control: no-store

...尽管这可能比用数百个相同的映像填充上游缓存更可取,特别是当它们运行在您自己的服务器上时。: -)

更新(2014-09-28):现在看起来像是Cache-Control: Chrome也需要no-store。

这是我的解决方案。这很简单。帧调度可以更好。

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">      
        <title>Image Refresh</title>
    </head>

    <body>

    <!-- Get the initial image. -->
    <img id="frame" src="frame.jpg">

    <script>        
        // Use an off-screen image to load the next frame.
        var img = new Image();

        // When it is loaded...
        img.addEventListener("load", function() {

            // Set the on-screen image to the same source. This should be instant because
            // it is already loaded.
            document.getElementById("frame").src = img.src;

            // Schedule loading the next frame.
            setTimeout(function() {
                img.src = "frame.jpg?" + (new Date).getTime();
            }, 1000/15); // 15 FPS (more or less)
        })

        // Start the loading process.
        img.src = "frame.jpg?" + (new Date).getTime();
    </script>
    </body>
</html>

不需要新的Date(). gettime()恶作剧。你可以通过使用jQuery .load()创建一个不可见的虚拟图像来欺骗浏览器,然后每次创建一个新的图像:

<img src="" id="dummy", style="display:none;" />  <!-- dummy img -->
<div id="pic"></div>

<script type="text/javascript">
  var url = whatever;
  // You can repeat the following as often as you like with the same url
  $("#dummy").load(url);
  var image = new Image();
  image.src = url;
  $("#pic").html("").append(image);
</script>