在html5浏览器中取消单个图像请求

我正在动态加载(大)图像以绘制到html5canvas,如下所示:

var t = new Image(); t.onload = ... t.src = 'http://myurl'; 

但每隔一段时间就想完全取消图像请求

我想出的唯一方法是将src设置为'' 。 即

 t.src = '' 

这适用于许多浏览器,但似乎只有Firefox实际上取消了对图像的http请求。

我通过禁用缓存并启用“模拟调制解调器速度”来测试Fiddler2 。 然后运行一个小提琴来测试取消图像请求。 (我很想听听关于如何测试这个的其他想法)

我知道有办法取消所有请求( 如本问题所示 ),但我只想取消一个。

有关其他方式(特别是在移动浏览器上)的任何想法吗?

这是我设法让它在所有现代浏览器(Chrome,Safari,Mobile-Safari,Firefox和IE9)中运行的唯一方式。

  • 加载一个空的隐藏iframe
  • image tag附加到iframebody
  • img.onload完成时,您可以使用该图像dom元素绘制到带有drawImage()的html5canvas
  • 如果要取消加载,请在iframecontentWindow (或IE中的contentDocument上的execCommand("stop", false)上发出stop() )。
  • 取消图像加载后,您可以重复使用iframe加载更多图像。

我为此创建了一个类,并将coffeescript代码(以及它的编译javascript)放在github上: Cancelable Html5 Image Loader

如果你想玩它,我也创建了一个jsfiddle来测试它 。 记得启动Fiddler2(或类似的东西),看看实际的网络请求是否真的被取消了。

您可以尝试使用window.stop()来停止所有请求,但不能停止单个请求。 在IE中,它不是window.stop()它是document.execCommand(“Stop”,false)。

如果你有其他的东西按要求进行,那么这样做会干扰它。 (您将跟进重新请求您仍然想要的资源,但这太像是努力工作)。


因此,如果您想停止对大图像的单个请求,您可以做的是将图像加载到隐藏的IFRAME中的文档中。 IFRAME的onload事件可用于将映像加载到主文档中,此时它应该被缓存(假设您已配置缓存指令)。

如果图像花费的时间太长,那么您可以访问IFRAME的contentWindow并向其发出停止命令。

您需要拥有尽可能多的IFRAME元素,因为可以同时请求图像。

我怀疑是否有一种跨浏览器的方式可以在没有黑客的情况下实现这一目标。 一个建议是向服务器端脚本发出一个AJAX请求,该脚本返回图像的Base64编码版本,然后您可以将其设置为src属性。 然后,如果您决定取消加载图像,则可以取消此请求。 如果您想要逐步显示图像,这可能会很困难。

我实际上遇到了同样的问题并做了一些测试。

我已经用iframe进行了一些测试并取得了一些成功。 在Firefox 3.6和Chrome上测试过。 对于测试,我使用了9张15Mb的图像 。 使用img预加载我几次杀了我的firefox(是的,在这台计算机上没有多少memoty),使用img“暂停”操作不会阻止图像加载如果请求已经开始,iframes挂起动作真的停止下载(因为我删除iframe)。 下一步将使用XMLHttpRequests进行测试。 由于此版本的测试代码使用braowser缓存行为形成图像URL以防止第二次加载,这也适用于ajax请求。 但也许使用iframe我可以找到一种方法直接从iframe中加载的图像中检索二进制数据(限制在相同的域URL上)。

这是我的测试代码(在Chrome上真的很快,可能用太多非常大的图像杀死你的Firefox):

 // jQuery.imageload.shared.list contains an array of oversized images url jQuery.each(imglist,function(i,imgsrc) { name = 'imageload-frame'; id = name + "-" + i; // with img it is not possible to suspend, the get is performed even after remove //var loader = jQuery('').attr('name', name).attr('id',id); var loader = jQuery('').attr('name', name).attr('id',id); //no cache on GET query taken from jQuery core // as we really want to download each image for these tests var ts = +new Date; // try replacing _= if it is there var ret = imgsrc.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2"); // if nothing was replaced, add timestamp to the end imgsrc = imgsrc + ((ret == imgsrc) ? (imgsrc.match(/\?/) ? "&" : "?") + "_=" + ts : ""); loader.css('display', 'none').appendTo('body'); loader.after( jQuery('') .text(' stop ') .attr('href','#') .click(function(){ loader.remove(); jQuery(this).text(' suspended '); }) ); // start the load - preload loader.attr('src',imgsrc); // when preload is done we provide a way to get img in document loader.load(function() { jQuery(this).next("a:first") .text(" retrieve ").unbind('click') .click(function() { var finalimg = jQuery(''); // browser cache should help us now // but there's maybe a way to get it direclty from the iframe finalimg.attr('src',loader[0].src); finalimg.appendTo('body'); }); }); }); 

编辑 ,这里是fillde测试它: http : //jsfiddle.net/wPr3x/