FormData 是 HTML5 中新增的一个 API,FormData 可以把数据封装成类似 HTML 表单的包含 key 和 value 的数据,主要用于 AJAX 提交。有了 FormData 在使用 AJAX 提交数据的时候就没必要使用类似拼接 URL 的方式来拼接数据了。FormData 除了能封装字符串外也能封装文件,使用 FormData 配合 AJAX 可实现无刷新上传文件,在配上进度条可以极大的提升用户体验。这里就来简单的写一下使用 FormData + AJAX 上传文件。

代码

HTML代码:

<input type="file" id="file">
<progress max="100" value="0" id="progress"></progress>
<button id="uploadBtn">开始上传</button>

上面包含一个文件选择控件,一个进度条控件和一个按钮。这个进度条控件是 HTML5 中新加入的,在不同浏览器下显示的外观也可能会不一样。如果要在所有浏览器下都显示一样的话,可以通过其他 HTML 标签嵌套并更改长度的方式来模拟进度条,不过在无障碍支持方面可能不太好。

JS代码:

var fileBox = document.querySelector('#file');  //  获取文件选择控件
var uploadBtn = document.querySelector('#upload-btn');  //  获取上传按钮
var progress = document.querySelector('#progress');  //  获取进度条

//  上传按钮点击
uploadBtn.onclick = function () {
    //  验证一下文件名是否为空
    if (fileBox.value == '') {
        alert('请选择文件');
        return false;
    }
    //  新建FormData对象
    var formData = new FormData();
    //  给FormData添加一个键值对,传入key和文件
    formData.append('file', fileBox.files[0]);
    // 新建XMLHttpRequest对象
    var xhr = new XMLHttpRequest();
    //  设置提交方式 url 是否异步
    xhr.open('post', 'server.php', true);
    //  设置请求头
    xhr.setRequestHeader('X-Request-With', 'XMLHttpRequest');

    //  此方法在上传进度改变时触发
    xhr.upload.onprogress = function (event) {
        //  是否包含进度数据
        if (event.lengthComputable) {
            //  根据已上传文件的大小和总大小计算出百分比
            var complete = Math.floor(event.loaded / event.total * 100);
            //  把百分比传给进度条
            progress.value = complete;
            //  把百分比传给进度条
            progress.innerHTML = complete;
        }
    }

    //  提交数据,传入已封装的FormData
    xhr.send(formData);

    //  此方法在成功提交并接收到数据的时候触发
    xhr.onreadystatechange = function () {
        //  验证一下是否全部接收完成
        if (xhr.readyState == 4) {
            //  在控制台输出接收到的数据
            console.log(xhr.responseText);
        }
    }
}

上面的代码包含注释,所以可能会有些长,实际上很简单,几行代码就能完成。

详细说明

下面是一些用到的对象和方法

FormData(form) 对象 建立 FormData 对象,可以传入 HTML 的 form 表单,也可以为空。

append(key, value) 方法 给 FormData 添加一个键值对,需要传入 keyvalue,类似表单的 namevalue,值可以传入字符串和文件。

下面是 XMLHttpRequest 的上传进度方法,有关 XMLHttpRequest 对象的使用可以看AJAX简单使用教程

upload.onprogress 事件 此事件只会在上传时触发,如果要监听上传进度需要传入 event

event.loaded 属性 已上传文件的字节数。

event.total 属性 文件的总大小 字节。

根据 event.loaded 已上传文件的字节数和 event.total 文件的总大小就可以计算出已上传的百分比。

相关文章: