【问题标题】:Aborting the xmlhttprequest中止 xmlhttprequest
【发布时间】:2011-12-17 22:04:54
【问题描述】:

我正在使用 HTML5 上传文件。我有一个按钮单击事件附加到函数uploadFile()。它工作正常。我还有一个单独的按钮来取消上传。我知道我们需要调用xhr.abort(),但是如何访问uploadCanceled 函数中的xhr 对象?我可以使 xhr 对象成为全局对象,但这不是正确的方法。有人可以在这里指导我吗?

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");
    } 

干杯

【问题讨论】:

  • 您是在xhr 被中止后尝试访问它(在uploadCanceled 内),还是需要访问它以便致电abort?您的问题和下面的 cmets 似乎并不一致。

标签: javascript html xmlhttprequest


【解决方案1】:

addEventListener 会将uploadCanceled 的上下文(this)设置为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/

【讨论】:

【解决方案2】:

您应该能够在您的 cancelledUpload 事件处理程序中引用“this”关键字。那是指 XMLHttpRequest。将其放入处理程序中:

this.abort();

【讨论】:

  • 感谢您的回复。但是如何在按钮的帮助下调用 uploadCanceled 函数呢?我知道如果我重新加载页面会调用它。我不认为我可以将它与 onClick 事件相关联,然后使用 this.abort() 对吗?
  • 看看这个:jsfiddle.net/yE8r3 代码不会在这里运行,而是展示如何将东西包装在一个闭包中。名为 s 的对象在闭包和点击处理程序中可见,但在闭包之外不可见。
  • 什么是canceledUpload 事件处理程序?
  • 对不起,应该说“uploadCanceled”,是原发帖人创建的函数名。
【解决方案3】:

中止所有 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();

【讨论】:

  • 如果没有必要,无论如何都要检查该条件。设置 .length 似乎不太好。您可以将它们一一弹出或将数组分配给[]
【解决方案4】:

您可以使用AbortController 和 fetch 来中止请求。

Demo

代码

const btn = document.getElementById('btn');
const btn2 = document.getElementById('btn2');
const url = 'https://www.mocky.io/v2/5185415ba171ea3a00704eed?mocky-delay=1000ms';

const ctrl;

btn.addEventListener('click', e => {
  ctrl = new AbortController();
  const signal = ctrl.signal;

  fetch(url, { signal })
    .then(r => r.json())
    .then(r => {
      console.log('Request result', r);
    }).catch(e => {
      console.error('Request was aborted. Error:', e);
    })
});

btn2.addEventListener('click', e => {
  ctrl.abort();
});

【讨论】:

猜你喜欢
  • 2010-11-20
  • 2015-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-20
  • 2021-01-06
  • 1970-01-01
  • 2010-09-18
相关资源
最近更新 更多