问题
在使用AntDesign
自带的umi-request
进行文件上传时遇到了无法上传二进制文件的问题。
原来是配置不当的问题。
解决
官方文档-上传组件:上传 Upload – Ant Design
文件上传配置:umijs/umi-request: A request tool based on fetch. (github.com)
核心配置
const formData = new FormData();
formData.append('file', file);
request('/api/v1/some/api', {
method: 'post', requestType: "form", data: formData
});
使用 FormData() 构造函数时,需要指定requestType: "form"
,然后浏览器会自动识别并添加请求头 "Content-Type: multipart/form-data"
,且参数依旧是表单提交时那种键值对,因此不需要开发者手动设置请求头 Content-Type,否则可能接口会报 500 的错误。
全部代码如下:
import React, { useState } from 'react';
import { Button, message, Modal, Upload, Typography } from 'antd';
const { Text, Link } = Typography;
const App = () => {
const [openUpload, setOpenUpload] = useState(false);
const [fileList, setFileList] = useState([]);
const [uploading, setUploading] = useState(false);
// 这里定义 request 上传参数
const uploadFileData = async (formData) => {
return request('/myserver/admin/demo/uploadBillFile', {
method: 'POST',
requestType: 'form',
data: formData,
params: { id: 1 },
headers: {
Authorization: localStorage.getItem('token'),
},
});
// 上传文件
const uploadModalSubmit = async () => {
if (fileList.length === 0) {
message.error('请先上传文件').then((r) => {});
return false;
}
const formData = new FormData();
formData.append('file', fileList[0]);
// console.log(fileList);
setUploading(true);
let response = await uploadFileData(formData);
if (response.code !== 0) {
setUploading(false);
message.error('上传失败:' + response.msg).then((r) => {});
return false;
}
message.success('上传成功!').then((r) => {});
setFileList([]);
setOpenUpload(false);
};
// 这里需要自定义取消,目前Modal的onOk与onCancel方法需要同时定义
const uploadModalCancel = () => {
setOpenUpload(false);
};
const upProps = {
name: 'file',
maxCount: 1,
onRemove: (file) => {
const index = fileList.indexOf(file);
const newFileList = fileList.slice();
newFileList.splice(index, 1);
setFileList(newFileList);
},
beforeUpload: (file) => {
//文件类型校验
const fileType = file.name.split('.').pop();
if (fileType !== 'xlsx') {
message.error(`上传失败:上传文件格式非 .xlsx`).then((r) => {});
return false;
}
setFileList([...fileList, file]);
return false;
},
};
return (
<>
<Button
onClick={() => {
setOpenUpload(true);
}}
>
<UploadOutlined />
上传账单
</Button>
<Modal
title="请上传账单文件 (.xlsx)"
centered
open={openUpload}
onOk={uploadModalSubmit}
confirmLoading={uploading}
onCancel={uploadModalCancel}
>
<div>
<Upload {...upProps}>
<Button icon={<UploadOutlined />}>点击上传</Button>
</Upload>
</div>
<div>
<br />
<Link href="/file_tpl/bill_demo.xlsx" target="_blank">
下载文件模板
</Link>
</div>
<div>
<Text type="secondary">重复上传相同月份文件,将以最后一次数据为准</Text>
</div>
</Modal>
</>
);
};
export default App;
参考
UmiJS:@umijs/plugin-request