Подтвердить что ты не робот

Отменить запрос одиночного изображения в браузерах html5

Я загружаю (большие) изображения динамически, чтобы рисовать в холст html5, примерно так:

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

Но время от времени хотелось бы полностью отменить запрос изображения.

Единственный способ, которым я придумал, - установить src в ''. то есть.

t.src = ''

Это работает во многих браузерах, но кажется, что только Firefox фактически отменяет HTTP-запрос для изображения.

Я протестировал это с помощью Fiddler2, отключив кеширование и включив "эмулировать скорость модема". Затем запустите скрипт, чтобы проверить отмену запроса изображения. (Мне бы хотелось услышать другие идеи о том, как проверить это)

Я знаю, что есть способы отменить все запросы (как в этом вопросе), но я хотел бы только отменить его.

Любые идеи по другим способам (особенно в мобильных браузерах) для этого?

4b9b3361

Ответ 1

Это единственный способ, которым мне удалось заставить его работать во всех современных браузерах (Chrome, Safari, Mobile-Safari, Firefox и IE9).

  • Загрузите пустой и скрытый iframe
  • добавить image tag в body в iframe
  • когда завершается img.onload, вы можете использовать этот элемент dom изображения для рисования на холсте html5 с помощью drawImage()
  • если вы хотите отменить загрузку, введите stop() в iframe contentWindow (или execCommand("stop", false) on contentDocument в IE).
  • после отмены загрузки изображения вы можете повторно использовать iframe для загрузки большего количества изображений.

Я создал класс для этого и поместил код coffeescript (и скомпилировал javascript) в github: Отменяемый загрузчик изображений Html5

Если вы хотите поиграть с ним, я также создал jsfiddle, чтобы проверить его. Не забудьте запустить Fiddler2 (или что-то в этом роде), чтобы увидеть, что фактический сетевой запрос действительно отменяется.

Ответ 2

Вы можете попробовать window.stop(), чтобы остановить все запросы, но не отдельные. В IE это не window.stop() it document.execCommand( "Стоп", false).

Если у вас есть другие вещи, идущие по запросу, то это будет мешать ему. (Вы будете следить за повторным запросом ресурсов, которые вы все еще хотите, но это слишком похоже на тяжелую работу).


Итак, если вы хотите остановить одиночный запрос для большого изображения, то вы можете загрузить изображение в документ в скрытом IFRAME. Событие onload IFRAME можно использовать для загрузки изображения в основной документ, и к этому времени он должен быть кэширован (предположим, что у вас есть директивы кэширования, настроенные для этого).

Если изображение занимает слишком много времени, вы можете получить доступ к содержимому IFRAME contentWindow и выдать команду stop.

У вас должно быть столько элементов IFRAME, сколько есть изображений, которые могут запрашиваться одновременно.

Ответ 3

Я сомневаюсь, что кросс-браузерный способ сделать это без хаков. Одно из предложений заключается в том, чтобы сделать запрос AJAX серверной стороне script, которая возвращает кодированную версию Base64 изображения, которую затем можно установить как атрибут src. Затем вы можете отменить этот запрос, если вы решите отменить загрузку изображения. Это может быть сложно, если вы хотите показывать изображение постепенно.

Ответ 4

У меня такая же проблема на самом деле и некоторые тесты.

Я провел несколько тестов с iframes и добился определенных успехов. Протестировано на Firefox 3.6 и Chrome. Для тестов я использовал 9 изображений 15 Мб. С предварительной загрузкой img я несколько раз убил свой firefox (да, не так много мемуатов на этом компьютере), используя img, действие "suspend" не предотвращает загрузку изображения, если запрос запущен, с iframes действие приостановки действительно останавливает загрузку (поскольку я удалить iframe). Следующий шаг будет тестироваться с помощью XMLHttpRequests. Поскольку эта версия моего тестового кода использует поведение кэша кэширования, формируйте URL-адрес изображения, чтобы предотвратить вторую загрузку, и это также работает с запросами ajax. Но, возможно, с iframes я мог бы найти способ получить двоичные данные из загруженного изображения в 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 maybe a way to get it direclty from the iframe
                finalimg.attr('src',loader[0].src);
                finalimg.appendTo('body');
            });
    });
});

отредактируйте, и вот это fillde, чтобы проверить его: http://jsfiddle.net/wPr3x/