xhr错误状态为0但脚本无论如何都会继续

时间:2014-03-18 21:57:53

标签: javascript ajax xmlhttprequest

我有一个完美的异步音频上传脚本,但是有一个问题困扰着我。它唯一令人困惑的是错误处理,因为错误是在xhr状态为0的情况下处理的,但是上传继续时看似没有错误。

xhr.upload.addEventListener("progress", keepPage(file,xhr),false);
xhr.upload.addEventListener("progress", uploadProgress,false);
xhr.upload.addEventListener("load", uploadComplete, false);
xhr.upload.addEventListener("error", uploadFailed(xhr.status), false);
xhr.upload.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "http://" + document.domain + "/script.php", true);
xhr.send(fd);
var uploading = true;
uploaded = false;
xhr.onreadystatechange=function(){
    if (xhr.readyState==4 && xhr.status==200) {
        var response = xhr.responseText;
        if (response == "success"){
            var uploaded = true;
            processSuccess();
        }
        else {
            var obj = $.parseJSON(response); //parse error JSON array
            errReport = obj.errReport
            uploadFailed(errReport);
        }
     }
}
uploading_tools(file, xhr, uploaded);

脚本开始上传后会立即触发error事件。我已将console.log(xhr.status)放在uploadFailed函数中,并且触发状态为0。

我理解当跨域调用ajax时会给出xhr状态为0,但正如您所看到的那样情况并非如此。

如果我无法摆脱这个烦人的错误,我将不得不在我的错误处理中忽略xhr状态为0,这是我想避免做的事情。

修改:

xhr.open("POST", "http://" + document.domain + "/script.php", true);
xhr.upload.addEventListener("progress", keepPage(file,xhr),false);
xhr.upload.addEventListener("progress", uploadProgress,false);
xhr.upload.addEventListener("load", uploadComplete, false);
xhr.upload.addEventListener("error", uploadFailed(xhr.status), false);
xhr.upload.addEventListener("abort", uploadCanceled, false);
xhr.send(fd);
var uploading = true;
uploaded = false;
xhr.onreadystatechange=function(){
    if (xhr.readyState==4 && xhr.status==200) {
        var response = xhr.responseText;
        if (response == "success"){
            var uploaded = true;
            processSuccess();
        }
        else {
            var obj = $.parseJSON(response); //parse error JSON array
            errReport = obj.errReport
            uploadFailed(errReport);
        }
     }
}
uploading_tools(file, xhr, uploaded);

1 个答案:

答案 0 :(得分:1)

在访问任何其他媒体资源或调用open()的任何其他方法之前,请务必致电XMLHttpRequest。否则会发生奇怪的行为。

修改 我刚看到光,你没有收到错误! 你有这一行:

xhr.upload.addEventListener("error", uploadFailed(xhr.status), false);

未将 uploadFailed()指定为错误事件的事件处理程序。 您正在调用uploadFailed(xhr.status) ,因此您将指定为事件处理程序函数的返回值!当然,uploadFailed肯定不返回任何内容,所以最后你没有错误处理程序。但是,当然,当执行此行时,您的函数被调用!由于xhr.send()的调用尚未发生,xhr.status0

您必须将行更改为

xhr.upload.addEventListener("error", uploadFailed, false);

就像你拥有其他人一样:

xhr.upload.addEventListener("progress", uploadProgress,false);
xhr.upload.addEventListener("load", uploadComplete, false);

新编辑

在回复你的评论时,它不起作用,因为你做的和你做的一样,而不是我告诉你做的。让我们看看我是否可以向你解释。

假设您的uploadFailed函数是这样的:

function uploadFailed(error) {
    console.log(error);
    return true;     //you won't have this line, but let's assume you do.
}

现在,你有了这段代码:

xhr.upload.addEventListener('error', uploadFailed(errReport), false);

嗯,这条线在做什么?正是这样:

var f = uploadFailed(errReport);   //uploadFailed is being called, not assigned to f
xhr.upload.addEventListener('error', f, false); //f is not a function, but the value 'true'!
你知道了吗?执行该行时,您正在调用函数并分配结果,而不是分配函数本身。如果您的问题是如何将错误值传递给错误函数,您可以这样做:

function uploadFailed() {
    console.log(this); //when you assign this function as an event handler, 
                       //'this' will be the object which fired the event (xhr.upload)
}

您不需要将xhr对象传递给函数,但是如果出于任何原因需要将错误作为参数传递,那么您必须这样做:

xhr.upload.addEventListener('error', function() { uploadFailed(xhr.status); }, false);

这样您就可以定义一个新的函数,该函数在其作用域中包含xhr对象,并可以将其传递给您的错误函数。

我希望你能得到函数和函数调用之间的区别,因为它是必不可少的。