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

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

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

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


当前回答

<img src='someurl.com/someimage.ext' onload='imageRefresh(this, 1000);'>

然后在下面的一些javascript

<script language='javascript'>
 function imageRefresh(img, timeout) {
    setTimeout(function() {
     var d = new Date;
     var http = img.src;
     if (http.indexOf("&d=") != -1) { http = http.split("&d=")[0]; } 

     img.src = http + '&d=' + d.getTime();
    }, timeout);
  }
</script>

这个做的是,当图像加载时,安排它在1秒内重新加载。我在不同类型的家庭安全摄像头的页面上使用这个。

其他回答

我有一个要求:1)不能添加任何?var=xx的图像2)它应该跨域工作

我真的很喜欢这个答案中的第4个选项,但是:

它在可靠地跨域工作方面存在问题(并且需要修改服务器代码)。

我的捷径是:

创建隐藏iframe 加载当前页面到它(是的,整个页面) iframe.contentWindow.location.reload(真正的); 重新设置图像源为其本身

在这里

function RefreshCachedImage() {
    if (window.self !== window.top) return; //prevent recursion
    var $img = $("#MYIMAGE");
    var src = $img.attr("src");
    var iframe = document.createElement("iframe");
    iframe.style.display = "none";
    window.parent.document.body.appendChild(iframe);
    iframe.src = window.location.href;
    setTimeout(function () {
        iframe.contentWindow.location.reload(true);
        setTimeout(function () {
            $img.removeAttr("src").attr("src", src);
        }, 2000);
    }, 2000);
}

我知道,setTimeout。您必须将其更改为适当的onload-events。

我使用下面的概念,首先将图像绑定到一个虚假的(缓冲区)url,然后将其绑定到有效的url。

imgcover.ImageUrl = ConfigurationManager.AppSettings["profileLargeImgPath"] + "Myapp_CoverPic_" + userid + "Buffer.jpg";

imgcover.ImageUrl = ConfigurationManager.AppSettings["profileLargeImgPath"] + "Myapp_CoverPic_" + userid + ".jpg";

通过这种方式,我强制浏览器使用有效的url进行刷新。

回答:你可以简单地使用fetch和缓存选项设置为'reload'来更新缓存:

fetch("my-image-url.jpg", {cache: 'reload', mode: 'no-cors'})

下面的函数将更新缓存并重新加载页面中的图像:

async function reloadImg(url) {
  await fetch(url, { cache: 'reload', mode: 'no-cors' })
  document.body.querySelectorAll(`img[src='${url}']`)
    .forEach(img => img.src = url)
}

它返回一个承诺,所以如果你愿意,你可以像await reloadImg("my-image-url.jpg")一样使用它。

如今,fetch API几乎在任何地方都可用(当然,IE除外)。

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

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的图片。完全冻结你的电脑只需要一个小时或更少的时间。我仍然不知道为什么浏览器缓存不限制在一个合理的最大值,但这绝对是一个缺点。

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

<!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>