You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Ant Design Upload+Axios遇404错误及默认上传行为修改需求

问题解决与代码修改

一、阻止选择文件后自动上传

Ant Design Upload组件默认会在选择文件后立即触发上传,要改为手动触发,只需给Upload组件添加beforeUpload={() => false}配置——该函数返回false时会直接阻止组件的自动上传流程。

修改后的Upload组件片段:

<Upload
  className="upload__file-container"
  listType="picture-card"
  accept="image/*"
  multiple={true}
  fileList={fileList}
  onPreview={handlePreview}
  onChange={handleChange}
  beforeUpload={() => false} // 新增:拦截自动上传
>
  {fileList.length >= 12 ? null : uploadButton}
</Upload>

二、排查并解决404错误

错误原因

  1. Axios请求配置冲突:原代码中axios.post同时传入了完整配置对象(含url、method、data)作为第三个参数,和前两个参数(url、formData)重复,导致请求参数异常
  2. Upload组件文件状态未同步:手动上传成功后,未更新fileList中文件的status为done,组件会默认判定上传失败,从而弹出错误提示

代码修复

  1. 简化Axios请求:移除重复的配置参数,规范请求写法
  2. 用useMutation回调管理状态:将上传成功/失败的状态更新逻辑移至useMutation的回调中,更符合React Query的使用规范
  3. 上传前重置状态:避免旧状态干扰新的上传流程

修改后的核心代码片段:

const handleUpload = useMutation(async (formData) => {
  // 简化请求配置,避免参数冲突
  const response = await axios.post(`${API_URL}/SendImage`, formData, {
    headers: {
      "Content-Type": "multipart/form-data",
    },
  });
  console.log(response.data);
  return response.data;
}, {
  onSuccess: () => {
    setUploading(false);
    setUploadingSuccess(true);
    setUploadingError(false);
  },
  onError: () => {
    setUploading(false);
    setUploadingError(true);
    setUploadingSuccess(false);
  }
});

const handleFileUpload = async () => {
  const formData = new FormData();

  fileList.forEach((file) => {
    formData.append("image", file.originFileObj);
  });

  // 上传前重置状态
  setUploading(true);
  setUploadingSuccess(false);
  setUploadingError(false);

  try {
    await handleUpload.mutateAsync(formData);
    setFileList([]); // 上传成功后清空文件列表
  } catch (error) {
    console.log(error, "Something went wrong");
  }
};

完整修改后的代码

export default function ScanNow() {
  const [previewVisible, setPreviewVisible] = useState(false);
  const [previewImage, setPreviewImage] = useState("");
  const [previewTitle, setPreviewTitle] = useState("");
  const [fileList, setFileList] = useState([]);
  const [uploading, setUploading] = useState(false);
  const [uploadSuccess, setUploadingSuccess] = useState(false);
  const [uploadError, setUploadingError] = useState(false);

  const handleCancel = () => setPreviewVisible(false);

  const handlePreview = async (file) => {
    if (!file.url && !file.preview) {
      file.preview = await new Promise((resolve) => {
        const reader = new FileReader();
        reader.readAsDataURL(file.originFileObj);
        reader.onload = () => resolve(reader.result);
      });
    }
    setPreviewImage(file.url || file.preview);
    setPreviewTitle(
      file.name || file.url.substring(file.url.lastIndexOf("/") + 1)
    );
    setPreviewVisible(true);
  };

  const handleUpload = useMutation(async (formData) => {
    const response = await axios.post(`${API_URL}/SendImage`, formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
    });
    console.log(response.data);
    return response.data;
  }, {
    onSuccess: () => {
      setUploading(false);
      setUploadingSuccess(true);
      setUploadingError(false);
    },
    onError: () => {
      setUploading(false);
      setUploadingError(true);
      setUploadingSuccess(false);
    }
  });

  const handleChange = ({ fileList: newFileList }) => setFileList(newFileList);

  const handleFileUpload = async () => {
    const formData = new FormData();

    fileList.forEach((file) => {
      formData.append("image", file.originFileObj);
    });

    setUploading(true);
    setUploadingSuccess(false);
    setUploadingError(false);

    try {
      await handleUpload.mutateAsync(formData);
      setFileList([]);
    } catch (error) {
      console.log(error, "Something went wrong");
    }
  };

  const uploadButton = (
    <div>
      <PlusOutlined />
      <div>Upload</div>
    </div>
  );

  return (
    <>
      <div className="upload">
        <p className="upload__heading">Upload Images to Scan</p>
        <div className="upload__wrapper">
          {uploading ? (
            <p>Please wait, uploading images...</p>
          ) : uploadSuccess ? (
            <p>Images uploaded successfully!</p>
          ) : uploadError ? (
            <p>Error while uploading image!</p>
          ) : null}
          <Upload
            className="upload__file-container"
            listType="picture-card"
            accept="image/*"
            multiple={true}
            fileList={fileList}
            onPreview={handlePreview}
            onChange={handleChange}
            beforeUpload={() => false}
          >
            {fileList.length >= 12 ? null : uploadButton}
          </Upload>
          {fileList.length === 0 ? (
            <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
          ) : (
            <Modal
              className="upload__preview-modal"
              open={previewVisible}
              title={previewTitle}
              onCancel={handleCancel}
              footer={null}
            >
              <img
                className="upload__preview"
                alt="scan-image"
                src={previewImage}
              />
            </Modal>
          )}
          {fileList.length > 0 && (
            <div>
              <button
                className="upload__button"
                type="primary"
                icon={<UploadOutlined />}
                onClick={handleFileUpload}
              >
                Upload
              </button>
            </div>
          )}
        </div>
      </div>
    </>
  );
}

额外说明

  • 若希望上传成功后保留文件列表并显示成功状态,可将setFileList([])替换为:
    setFileList(fileList.map(file => ({ ...file, status: 'done' })))
    
  • 请确认API_URL变量已正确定义,服务器接口/SendImage的路径完全匹配,避免路径拼写错误导致404

内容的提问来源于stack exchange,提问作者user19662721

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 06:27:56