ES6 ANTD
背景
在做需求时,遇到点击按钮进行文件的上传,我需要处理以下几点:
- 点击选择文件按钮跳出选择文件的小窗
- 限定选择文件类别为excel的两种格式
- 每次只能上传一个文件,文件大小低于2M
- 选择文件的名称呈现在按钮左侧,可以删除,再次点击选择文件按钮,新的文件替换之前的文件
- 点击开始上传按钮后,选择文件按钮失效,开始上传按钮文字变为上传中
……以上的等等需求。
难点
因为使用了antd封装后的Upload组件,像跳出选择框,限制文件类型,替换当前文件列表,单选等都变得很容易。 同时,点击开始上传按钮进行上传,则需要使用Upload组件中的beforeUpload或customRequest(通过覆盖默认的上传行为,可以自定义自己的上传实现,这个在文末我会稍作阐述。)
我遇到的需求是,后台请求要求为:
请求头: headers: {'content-type': 'application/form-data' }
请求参数:multipartFile: file
正常上传文件,我们可以使用form表单,FormData,jquery.form.js-表单插件来进行。这次使用FormData进行文件的上传,但是我没用过,所以进行了学习
解决过程
Upload参数配置
先看下Upload的参数列表,我只截取我用到的部分,其余参数可以自行到官网查看-Upload



defaultFileList 会默认显示在上传显示区,FileList 包含你已经选择的文件,所以不要再添加。 代码如下:
//支持的格式,xls,xlsx
supportType = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
//
<Upload
action='//这里用不到'
fileList={your.fileList} //呈现上传文件列表
accept={this.supportType} //支持的上传格式
onRemove={this.handleRemove} //移除文件时的调用
beforeUpload={this.handleBeforeUpload} // return false,用来自己操控上传
>
<div className='upload-select-btn'>
<Button type='primary' disabled={your.chooseButtonDisabled || your.isUploading || your.isProcessing}>
选择文件
</Button>
</div>
</Upload>
实际效果为:


按照官方文件列表的呈现区域为按钮下方,这里通过CSS进行了覆盖,重新调整了呈现位置和呈现区域的样式,呈现文字的大小。
BeforeUpload
如果不写BeforeUpload会默认选择完文件直接上传,所以我们需要在BeforeUpload里return false
来实现手动点击按钮进行上传。
window.File实例会包含文件的修改时间,大小(size),文件名,文件的mime类型等。
//beforeUpload 附带参数当前选择的file文件,fileList文件列表
handleBeforeUpload = (file, list) => {
const LIMIT_BYTE = 2048; // 限定2M, 1024 byte = 1 K
if (this.supportType.includes(file.type)) { //一些限定
if (Math.round(file.size / 1024) < LIMIT_BYTE) {
//更新当前FileList列表,替换为新的list
} else {
//提示文件太大错误
}
} else {
// 提醒文件格式不满足要求
}
return false; //一定要return false,阻止自动上传
};
点击开始上传按钮后,我们要进行文件上传前的处理,这里就涉及了FormData的知识。
handleUpload = () => {
const file = //你保存下来的fileList
const formData = new FormData(); //new FormData
formData.append('multipartFile', file[0]); //键值对形式,将一个文件添加到formData,因为每次只上传一个文件
//更新上传中状态
//Ajax 函数,调用你的接口函数,对接上传接口并处理返回的文件
.then((response) => {
//去过上传成功,更新上传状态
//处理上传后返回的信息
})
.catch(() => {
//如果上传失败,进行的相关处理
});
};
FormData相关知识
在以前我们常通过建立form表单,进行文件的上传。
<form name='' action='接口地址' method='请求方法' enctype='multipart/form-data'>
<input type='file'>
…
</form>
表单<form>
属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:
①application/x-www-form-urlencoded(默认值) ②multipart/form-data
form表单在你不写enctype属性时,默认值是enctype="application/x- www-form-urlencoded".
但是,在XMLHttpRequest2定义了FormData类型,它是为序列化表以及创建与表单格式相同的数据(用于XHR传输)提供便利。
先看下官方对FormData的定义:“FormData对象用以将数据编译成键值对,以便用XMLHttpRequest来发送数据。其主要用于发送表单数据,但亦可用于发送带键数据(keyed data),而独立于表单使用。
如果表单enctype属性设为multipart/form-data ,则会使用表单的submit()方法来发送数据,从而,发送数据具有同样形式”。
首先我们创建一个空FormData:
var formData = new FormData();
再调用它的方法append添加数据,例如。
formData.append('multipartFile', file,"named file.txt" )
使用append()方法时,可以通过第三个可选参数设置发送请求的头 Content-Disposition 指定文件名。如果不指定文件名(或者不支持该参数时),将使用名字“blob”。
FormData()储存数据的形式是键值对,即一对“key/value”构成一条数据,key唯一,可以对应多个value。
formData还有set,get,getAll,delete,entries,has,key,values等方法。 详情见MDN-Form
现在formData有了我们上传的键值对形式的数据,再使用XHR.send(formData)将数据发送到后台接口进行文件的异步处理。
xhr.open("post",'url');
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");//设置请求头格式
如此我们就实现了文件的上传处理。
接下来,我来学习下Upload组件中的customRequst方法来覆盖默认上传行为,实现异步上传。
customRequest
官方对于该方法的参数列表如下:

//携带那么多参数而来的customRequest
customRequest({
action,
data,
file,
filename,
headers,
onError,
onProgress,
onSuccess,
withCredentials,
})
customRequest = (option) => {
const file = option.file;
const filename = option.filename;
var formData = new FormData();
formData.append(filename,file);
//Ajax部分-官网使用reqwest
//processData: false
}
Over。
有疑问可以评论~~~