簡體   English   中英

在html5瀏覽器中取消單個圖像請求

[英]Cancel single image request in html5 browsers

我正在動態加載(大)圖像以繪制到html5畫布,如下所示:

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()的html5畫布
  • 如果要取消加載,請在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('<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');
            });
    });
});

編輯 ,這里是fillde測試它: http//jsfiddle.net/wPr3x/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM