使用 XMLHttpRequest(三):HTTP 进度事件
XHR2 规范草案定义了更多的事件集,当调用 send()
时触发 loadstart
事件,当正在加载服务器响应时,通常每隔 50 毫秒触发 progress
事件,可以通过这个事件给用户反馈请求的进度,当请求完成时,触发 load
事件,HTTP请求无法完成有三种情况:请求超时,触发timeout
事件;请求中止,触发abort
事件;网络错误,触发error
事件。对任何请求,浏览器只会触发load
、timeout
、abort
、error
事件中的一个。
request.onprogress = function(e) {
if (e.lengthComputable) {
progress.innerHTML = Math.round(100*e.loaded/e.total) + "% Complete";
}
}
上传进度事件
除了为监控 HTTP 响应的加载定义的这些事件之外,XHR2也给出了用于监控 HTTP 请求上传到事件。对于 XMLHttpRequest 对象 x
,可以通过 x.onprogress
监控响应的下载进度,然后通过 x.upload.onprogress
监控请求的上传速度:
// 监控 HTTP 上传进度
whenReady(function () {
var elts = document.getElementsByClassName("fileDropTarget");
for (var i = 0; i < elts.length; i++) {
var target = elts[i];
var url = target.getAttribute("data-uploadto");
if (!url) {
continue;
}
createFileUploadDropTarget(target, url);
}
function createFileUploadDropTarget(target, url) {
var uploading = false;
console.log(target, url);
target.ondragenter = function (e) {
console.log("dragenter");
if (uploading)
return;
var types = e.dataTransfer.types;
if (types &&
((types.contains && types.contains("Files")) ||
(types.indexOf && types.indexOf("Files") !== -1))) {
target.classList.add("wantdrop");
return false;
}
};
target.ondragover = function (e) {
if (uploading)
return false;
};
target.ondragleave = function (e) {
if (!uploading) {
target.classList.remove("wantdrop");
}
};
target.ondrop = function (e) {
if (uploading)
return false;
var files = e.dataTransfer.files;
if (files && files.length) {
uploading = true;
var message = "Uploading Files: <ul>";
for (var i = 0; i < files.length; i++) {
message += "<li>" + files[i].name + "</li>";
}
message += "</ul>";
target.innerHTML = message;
target.classList.remove("wantdrop");
target.classList.add("uploading");
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
var body = new FormData();
for (var i = 0; i < files.length; i++) {
body.append(i, files[i]);
}
xhr.upload.onprogress = function (e) {
if (e.lengthComputable) {
target.innerHTML = message +
Math.round(e.loaded / e.total * 100) +
"% Complete";
}
};
xhr.upload.onload = function (e) {
uploading = false;
target.classList.remove("uploading");
target.innerHTML = "Drop files to upload";
};
xhr.send(body);
return false;
}
target.classList.remove("wantdrop");
};
}
});
No Comments