使用 XMLHttpRequest(三):HTTP 进度事件


XHR2 规范草案定义了更多的事件集,当调用 send() 时触发 loadstart 事件,当正在加载服务器响应时,通常每隔 50 毫秒触发 progress 事件,可以通过这个事件给用户反馈请求的进度,当请求完成时,触发 load 事件,HTTP请求无法完成有三种情况:请求超时,触发timeout事件;请求中止,触发abort事件;网络错误,触发error事件。对任何请求,浏览器只会触发loadtimeoutaborterror事件中的一个。

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

点赞 取消点赞 收藏 取消收藏

<< 上一篇: 使用 XMLHttpRequest(二):编码请求主体

>> 下一篇: 使用 XMLHttpRequest(四):中止请求和超时