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

标签 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);

最佳答案

在访问 XMLHttpRequest 的任何其他属性或调用任何其他方法之前,始终调用 open()。否则可能会发生奇怪的行为。

编辑 我刚刚看到了光,你没有收到错误! 你有这一行:

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 对象,并且可以将其传递给您的错误函数。

我希望您能够区分函数和函数调用之间的区别,因为这是必不可少的。

关于javascript - xhr 错误状态为 0,但脚本无论如何都会继续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22491893/

相关文章:

c# - 使用 WebClient c#

javascript - XMLHttpRequest 仅在加载 xml 文件时在本地使用 Firefox

javascript - 加载所有图像(包括缓存图像)后的 jquery 事件?

php - 将列表从 php 或 xmlhttp.responseText 传递到 javascript

javascript - jquery追加后运行函数

javascript - 石头、剪刀、布游戏动画。

javascript - 谷歌浏览器 - 使用 ajax 时停滞不前,如何解决?

javascript - 两个窗口之间交换信息

javascript - 如何正确使用 Javascript 异步eachLimit

javascript - CasperJS sendAjax 返回 null