Annulla la richiesta di una singola immagine nei browser html5

Sto caricando (grandi) immagini dynamicmente per disegnare in una canvas html5, qualcosa del genere:

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

Ma ogni tanto vorrei annullare completamente la richiesta di immagine .

L’unico modo in cui sono arrivato è impostare src su '' . vale a dire

 t.src = '' 

Funziona in molti browser, ma sembra che solo Firefox annulli effettivamente la richiesta http per l’immagine.

Ho provato questo con Fiddler2 disabilitando il caching e abilitando “emulate modem speed”. Quindi esegui un violino per testare l’annullamento di una richiesta di immagine. (Mi piacerebbe sentire altre idee su come testare questo)

So che ci sono modi per cancellare tutte le richieste ( come in questa domanda ), ma vorrei cancellarne solo una.

Qualche idea su altri modi (specialmente sui browser mobili) per fare questo?

Questo è l’unico modo in cui sono riuscito a farlo funzionare in tutti i browser moderni (Chrome, Safari, Mobile-Safari, Firefox e IE9).

  • Carica un iframe vuoto e nascosto
  • aggiungi un image tag al body iframe
  • al termine di img.onload , puoi utilizzare quell’elemento dom dell’immagine per disegnare su una canvas html5 con drawImage()
  • se si desidera annullare il caricamento, inviare uno stop() sul contentWindow (o execCommand("stop", false) iframe su contentDocument in IE).
  • dopo aver annullato il caricamento di un’immagine, puoi riutilizzare l’iframe per caricare più immagini.

Ho creato una class per questo, e ho inserito il codice coffeescript (ed è compilato in javascript) su github: Loadable Image Html5 cancellabile

Se vuoi giocare con esso, ho anche creato un jsfiddle per provarlo . Ricorda di avviare Fiddler2 (o qualcosa di simile) per vedere che la richiesta di rete effettiva viene effettivamente cancellata.

Puoi provare window.stop () per interrompere tutte le richieste, ma non quelle individuali. In IE, non è window.stop () è document.execCommand (“Stop”, false).

Se hai altre cose in corso su richiesta, questo potrebbe interferire con esso. (Seguirai una richiesta per le risorse che desideri ancora, ma è troppo simile a un duro lavoro).


Pertanto, se si desidera interrompere una singola richiesta per un’immagine di grandi dimensioni, ciò che si potrebbe fare è caricare l’immagine in un documento all’interno di un IFRAME nascosto. L’evento onload dell’IFRAME può essere utilizzato per caricare l’immagine nel documento principale, in base alla quale deve essere memorizzata nella cache (presumendo che le direttive di memorizzazione nella cache siano configurate per farlo).

Se l’immagine impiega troppo tempo, puoi accedere alla finestra dei contenuti di IFRAME e impartire un comando di arresto.

È necessario disporre di tanti elementi IFRAME quante sono le immagini che possono essere richieste contemporaneamente.

Dubito che ci sia un modo cross-browser per farlo accadere senza hack. Un suggerimento è di creare una richiesta AJAX per uno script sul lato server che restituisce una versione codificata Base64 dell’immagine che è ansible impostare come attributo src . Quindi puoi annullare questa richiesta se decidi di annullare il caricamento dell’immagine. Questo potrebbe essere difficile se si desidera mostrare l’immagine progressivamente comunque.

Ho effettivamente lo stesso problema e ho fatto alcuni test.

Ho fatto alcuni test con iframe e ho avuto qualche successo. Testato su Firefox 3.6 e Chrome. Per i test ho usato 9 immagini da 15Mb . Con img preloading ho ucciso più volte il mio firefox (sì, non molto memoty su questo computer), usando img l’azione “suspend” non impedisce il caricamento dell’immagine se la richiesta è iniziata, con iframe l’azione suspend interrompe davvero il download (come rimuovere l’iframe). Il prossimo passo sarà testare con XMLHttpRequests . Poiché questa versione del mio codice test utilizza il comportamento della cache del braowser dall’URL dell’immagine per impedire un secondo caricamento e questo funziona anche con le richieste Ajax. Ma forse con iframe potrei trovare un modo per recuperare direttamente i dati binari dall’immagine caricata in iframe (con limitazioni sugli stessi URL di dominio).

Questo è il mio codice di test (molto veloce su Chrome, potrebbe uccidere il tuo firefox con troppe immagini molto grandi):

 // 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 performsd 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'); }); }); }); 

modifica e qui è fillde per testarlo: http://jsfiddle.net/wPr3x/