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

Javascript 在html5浏览器中取消单个图像请求,javascript,jquery,image,canvas,mobile-safari,Javascript,Jquery,Image,Canvas,Mobile Safari,我正在动态加载(大)图像以绘制到html5画布中,类似于: var t = new Image(); t.onload = ... t.src = 'http://myurl'; 但是每隔一段时间就会想完全取消图像请求 我想到的唯一方法是将src设置为'。i、 e t.src = '' 这在许多浏览器中都可以使用,但似乎只有Firefox真正取消了对图像的http请求 我通过禁用缓存和启用“模拟调制解调器速度”对此进行了测试。然后跑步(我想听听关于如何测试这个的其他想法) 我知道有很多方法可

我正在动态加载(大)图像以绘制到html5画布中,类似于:

var t = new Image();
t.onload = ...
t.src = 'http://myurl';
但是每隔一段时间就会想完全取消图像请求

我想到的唯一方法是将
src
设置为
'
。i、 e

t.src = ''
这在许多浏览器中都可以使用,但似乎只有Firefox真正取消了对图像的http请求

我通过禁用缓存和启用“模拟调制解调器速度”对此进行了测试。然后跑步(我想听听关于如何测试这个的其他想法)

我知道有很多方法可以取消所有请求(),但我只想取消一个

有没有其他方法(特别是在移动浏览器上)可以做到这一点的想法?

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

如果你有其他东西在按要求进行,那么这样做会干扰它。(您可能会再次请求您仍然需要的资源,但这太像艰苦的工作了)


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

如果映像占用的时间太长,则可以访问IFRAME的contentWindow并向其发出stop命令


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

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

实际上我也有同样的问题,并做了一些测试

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

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

//jQuery.imageload.shared.list包含一个超大图像url数组
每个(imglist,function(i,imgsrc){
名称='imageload frame';
id=名称+“-”+i;
//使用img无法挂起,即使在删除后也会执行get

//var loader=jQuery(“这是我设法让它在所有现代浏览器(Chrome、Safari、Mobile Safari、Firefox和IE9)中工作的唯一方法

  • 加载一个空且隐藏的
    iframe
  • 图像标签
    附加到
    iframe中的
    正文
  • img.onload
    完成时,您可以使用该图像dom元素使用
    drawImage()
  • 如果要取消加载,请在
    iframe
    contentWindow
    上发出
    stop()
    (或IE中
    contentDocument
    上发出
    execCommand(“stop”,false)
  • 取消图像加载后,可以重用iframe加载更多图像
我为此创建了一个类,并将coffeescript代码(它是经过编译的javascript)放在github上:


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

要小心
t.src='
,规范对应该发生什么是含糊不清的。请看右边…一些浏览器正在请求页面的url(或基本url)尝试加载带有
src=''
的图像。在Firefox下,设置
t.src=null
也会取消请求,但不会对其他图像执行任何操作。较新的(当前工作)规范说(在某些情况下)这…有点。在Firefox下将
src
设置为内联图像也会取消以前的请求:
t.src='data:image/gif;base64,R0lGOD…
在空图像中查看src使页面重新加载请求,从而使您进入页面。因此,当您在帖子之后到达页面时,浏览器将默默地重做帖子。这真是一个好消息射中自己一只脚的好方法。“但不是个别的”…您能对此进行备份吗?您提供的其余信息已在问题中陈述并链接到。您只能停止窗口的所有正在进行的请求。这给了我一个想法,请参阅添加到我的答案中的其他信息!好主意,但与此相关的几个问题。首先是数据传输量d多了33%。(base64:24位->32位)。然后(特别是在移动浏览器上),它给javascript带来了很大的内存压力,因为数据必须以字符串形式存储在JS中,然后它还有一个额外的base64解码步骤。对于大文件(200K+)这可能会造成伤害。但这在某些情况下肯定能很好地工作。这是一个很好的观点。当我提出这个想法时,我没有考虑开销。显然,在使用AJAX读取二进制文件方面做了一些努力。我从来没有这样做过
// 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('<img />').attr('name', name).attr('id',id);
    var loader = jQuery('<iframe />').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('<a>')
            .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('<img />');
                // 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');
            });
    });
});