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

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

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

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


当前回答

基于Doin的#4代码,下面的示例利用文档简化了代码。在iframe中写入而不是src来支持CORS。也只关注破坏浏览器缓存,而不是重新加载页面上的每个图像。

下面是用typescript编写的,并使用了angular的$q promise库,只是供参考,但应该很容易移植到普通javascript。方法意味着存在于typescript类中。

返回一个承诺,该承诺将在iframe完成重新加载时得到解决。没有经过严格测试,但对我们来说很好。

    mmForceImgReload(src: string): ng.IPromise<void> {
        var deferred = $q.defer<void>();
        var iframe = window.document.createElement("iframe");

        var firstLoad = true;
        var loadCallback = (e) => {
            if (firstLoad) {
                firstLoad = false;
                iframe.contentWindow.location.reload(true);
            } else {
                if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
                deferred.resolve();
            }
        }
        iframe.style.display = "none";
        window.parent.document.body.appendChild(iframe);
        iframe.addEventListener("load", loadCallback, false);
        iframe.addEventListener("error", loadCallback, false);
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write('<html><head><title></title></head><body><img src="' + src + '"></body></html>');
        doc.close();
        return deferred.promise;
    }

其他回答

一种解决方法是像建议的那样笨拙地添加一些get查询参数。

更好的答案是在HTTP报头中发出两个额外的选项。

Pragma: no-cache
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Cache-Control: no-cache, must-revalidate

通过提供过去的日期,它不会被浏览器缓存。缓存控制是在HTTP/1.1中添加的,必须重新验证标签表明代理永远不应该提供旧的映像,即使是在可减轻的情况下,而Pragma: no-cache对于当前的现代浏览器/缓存来说并不是真正必要的,但可能有助于一些复杂的破碎的旧实现。

尝试使用一个没有价值的查询字符串使其成为一个唯一的url:

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

    setTimeout(updateImage, 1000);
}
<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秒内重新加载。我在不同类型的家庭安全摄像头的页面上使用这个。

下面的代码用于在单击按钮时刷新图像。

function reloadImage(imageId) {
   imgName = 'vishnu.jpg'; //for example
   imageObject = document.getElementById(imageId);
   imageObject.src = imgName;
}

<img src='vishnu.jpg' id='myimage' />

<input type='button' onclick="reloadImage('myimage')" />

基于Doin的#4代码,下面的示例利用文档简化了代码。在iframe中写入而不是src来支持CORS。也只关注破坏浏览器缓存,而不是重新加载页面上的每个图像。

下面是用typescript编写的,并使用了angular的$q promise库,只是供参考,但应该很容易移植到普通javascript。方法意味着存在于typescript类中。

返回一个承诺,该承诺将在iframe完成重新加载时得到解决。没有经过严格测试,但对我们来说很好。

    mmForceImgReload(src: string): ng.IPromise<void> {
        var deferred = $q.defer<void>();
        var iframe = window.document.createElement("iframe");

        var firstLoad = true;
        var loadCallback = (e) => {
            if (firstLoad) {
                firstLoad = false;
                iframe.contentWindow.location.reload(true);
            } else {
                if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
                deferred.resolve();
            }
        }
        iframe.style.display = "none";
        window.parent.document.body.appendChild(iframe);
        iframe.addEventListener("load", loadCallback, false);
        iframe.addEventListener("error", loadCallback, false);
        var doc = iframe.contentWindow.document;
        doc.open();
        doc.write('<html><head><title></title></head><body><img src="' + src + '"></body></html>');
        doc.close();
        return deferred.promise;
    }