2011-10-29 3 views
15

Я использую HTML5 для загрузки файлов. У меня есть событие нажатия кнопки, присоединенное к функции uploadFile(). Оно отлично работает. У меня также есть отдельная кнопка для отмены загрузки. Я знаю, что нам нужно вызвать xhr.abort(); Но как мне получить доступ к объекту xhr в функции uploadCanceled? Я могу сделать объект xhr глобальным, но это не так. Может ли кто-нибудь направить меня сюда?Отмена xmlhttprequest

function uploadFile(){ 
    var filesToBeUploaded = document.getElementById("fileControl"); 
    var file = filesToBeUploaded.files[0]; 
    var xhr= new XMLHttpRequest(); 
    xhr.upload.addEventListener("progress", uploadProgress, false); 
    xhr.addEventListener("load", uploadComplete, false); 
    xhr.addEventListener("error", uploadFailed, false); 
    xhr.addEventListener("abort", uploadCanceled, false); 


    xhr.open("POST", "upload.php", true); 

    var fd = new FormData(); 
    fd.append("fileToUpload", file); 
    xhr.send(fd); 
} 


    function uploadCanceled(evt) { 
     alert("Upload has been cancelled"); 
    } 

Приветствия

+0

Вы пытаетесь получить доступ к 'xhr' как только он был прерван (в' uploadCanceled') или сделать вас нужно связаться с ним, чтобы вы могли называть 'abort'? Ваш вопрос и ваши комментарии ниже не совпадают друг с другом. –

ответ

16

addEventListener установит контекст (this) из uploadCanceled в xhr:

function uploadCanceled(evt) { 
    console.log("Cancelled: " + this.status); 
} 

Пример: http://jsfiddle.net/wJt8A/


Если, вместо этого, вам нужно триггер xhr.abort через кнопку «Отмена», вы можете вернуть ссылку и добавить слушателей вам нужно после этого:

function uploadFile() { 
    /* snip */ 
    xhr.send(fd); 

    return xhr; 
} 

document.getElementById('submit').addEventListener('click', function() { 
    var xhr = uploadFile(), 
     submit = this, 
     cancel = document.getElementById('cancel'); 

    function detach() { 
     // remove listeners after they become irrelevant 
     submit.removeEventListener('click', canceling, false); 
     cancel.removeEventListener('click', canceling, false); 
    } 

    function canceling() { 
     detach(); 
     xhr.abort(); 
    } 

    // detach handlers if XHR finishes first 
    xhr.addEventListener('load', detach, false); 

    // cancel if "Submit" is clicked again before XHR finishes 
    submit.addEventListener('click', canceling, false); 

    // and, of course, cancel if "Cancel" is clicked 
    cancel.addEventListener('click', canceling, false); 
}, false); 

Пример: http://jsfiddle.net/rC63r/1/

+0

Спасибо за ответ. Это очень помогло. – lewis

+0

Является ли этот код совместимым с IE7? – moderns

+2

@moderns Не совсем. Основное внимание в этом ответе, 'xhr.status' и' xhr.abort() ', поддерживаются в IE7. Но ['addEventListener()'] (https://developer.mozilla.org/en-US/docs/Web/API/EventTarget.addEventListener) поддерживается только IE9 и более поздними версиями. Предыдущие версии вместо этого использовались ['attachEvent()'] (http://msdn.microsoft.com/en-us/library/ie/ms536343.aspx). «[Правильное использование addEventListener()/attachEvent()?] (Http://stackoverflow.com/questions/2657182/correct-usage-of-addeventlistener-attachevent)». Кроме того, 'FormData' из вопроса требует [IE 10 и позже] (http://caniuse.com/#feat=xhr2). –

2

Вы должны быть в состоянии ссылаться на «это» ключевое слово в обработчике события canceledUpload. Это относится к XMLHttpRequest. Поместите это в обработчике:

this.abort(); 
+0

благодарит за ответ. Но как я могу вызвать функцию uploadCanceled с помощью кнопки? Я знаю, что он будет вызываться, если я перезагружу страницу. Я не думаю, что могу связать его с событием onClick, а затем использовать this.abort() правильно? – lewis

+0

Посмотрите на: http://jsfiddle.net/yE8r3/ Код не работает здесь, но показывает, как обернуть вещи в закрытии. Объект с именем s отображается внутри закрытия и обработчик кликов, но не за пределами закрытия. – dnuttle

+0

Что такое обработчик события 'cancelUpload'? – stevemao

0

Прервать все XMLHttpRequest:

var array_xhr = new Array(); 
function uploadFile(){ 
    ... 
    var xhr = new XMLHttpRequest(); 
    array_xhr.push(xhr); 
    ... 
} 

function abort_all_xhr(){ 
    if (array_xhr.length>0) { 
     for(var i=0; i<array_xhr.length; i++){ 
      array_xhr[i].abort(); 
     } 
     array_xhr.length = 0; 
    }; 
} 

abort_all_xhr(); 
+1

, если это не нужно, для проверок, которые в любом случае будут выполнены. Установка .length не показалась хорошей. Вы можете поместить их по одному или назначить массив [] – daghan