Ant-Design上传文件之umi-request注意事项

问题

在使用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

记录 umi-request上传文件的坑 – 掘金 (juejin.cn)

Author: thinkwei

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注