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错误
错误原因
- Axios请求配置冲突:原代码中
axios.post同时传入了完整配置对象(含url、method、data)作为第三个参数,和前两个参数(url、formData)重复,导致请求参数异常 - Upload组件文件状态未同步:手动上传成功后,未更新fileList中文件的
status为done,组件会默认判定上传失败,从而弹出错误提示
代码修复
- 简化Axios请求:移除重复的配置参数,规范请求写法
- 用useMutation回调管理状态:将上传成功/失败的状态更新逻辑移至useMutation的回调中,更符合React Query的使用规范
- 上传前重置状态:避免旧状态干扰新的上传流程
修改后的核心代码片段:
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
相关产品推荐
相关产品推荐

