我有一个完美的异步音频上传脚本,但是有一个问题困扰着我。它唯一令人困惑的是错误处理,因为错误是在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);
答案 0 :(得分:1)
在访问任何其他媒体资源或调用open()
的任何其他方法之前,请务必致电XMLHttpRequest
。否则会发生奇怪的行为。
修改强> 我刚看到光,你没有收到错误! 你有这一行:
xhr.upload.addEventListener("error", uploadFailed(xhr.status), false);
您未将 uploadFailed()
指定为错误事件的事件处理程序。 您正在调用uploadFailed(xhr.status)
,因此您将指定为事件处理程序函数的返回值!当然,uploadFailed
肯定不返回任何内容,所以最后你没有错误处理程序。但是,当然,当执行此行时,您的函数被调用!由于xhr.send()
的调用尚未发生,xhr.status
为0
。
您必须将行更改为
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
对象,并可以将其传递给您的错误函数。
我希望你能得到函数和函数调用之间的区别,因为它是必不可少的。