一、产品需求
用户可以自由选择(选择后可以删除、重新选)一个文件,文件选择好后点击上传按钮进行上传。
二、代码实现
1.state定义
this.state = { showModal: false, fileList: [], //文件列表,用于控制upload组件 uploading: false //上传按钮loading显示控制 }
2.Upload组件的文件选择变化处理,上传按钮动作处理(使用axios上传文件)
handleFileChange = ({file, fileList}) => { //处理文件change,保证用户选择的文件只有一个 this.setState({ 'fileList': fileList.length? [fileList[fileList.length - 1]] : [] }) } handleUpload = () => { if(!this.state.fileList.length) { message.warning("请选择要上传的文件") } const formData = new FormData() formData.append('file', this.state.fileList[0].originFileObj) this.setState({ uploading: true }) Axios.defaults.baseURL='https://jsonplaceholder.typicode.com/' Axios({ method: 'post', url: 'posts', data: formData, headers: { "Content-Type": "multipart/form-data"} }).then(({data}) => { message.success("上传成功") console.log(data) }).catch((err) =>{ console.log(err) }).finally(() =>{ this.setState({ uploading: false }) }) }
3.Upload组件使用
false} onChange={this.handleFileChange} >
4.效果
三、注意事项
1.antd的Upload组件,在用户选择文件后会马上进行上传,可以自定义beforeUpload方法进行控制,若直接返回false就不上传“beforeUpload={(f, fList) => false}”。
2.要想post上传文件,发送的数据需要为FormData而不是json之类的,所以代码会先new一个FormData,然后把用户选择的文件添加到FormData里面去。(直接console.log打印FormData永远都是空,所以不要尝试直接打印FormData判断文件是否添加成功)
3.antd选择后的文件file是经过包装的数据,添加到formData时需要取file.originFileObj。官方案例没这么写,但用axios上传时如果直接使用file,后台会出现死活找不到数据的情况(坑了我好几个小时才找到原因)。
4.axios的请求参数中需要加入“headers: { "Content-Type": "multipart/form-data"}”,来申明传的是表单数据。