React上传XML文件 Ant Design的upload组件如何自定义请求

12次阅读

Ant Design Upload 组件默认使用 xmlHttpRequest 且不走 axios/fetch,必须通过 customRequest 手动实现上传逻辑以支持 Authorization、timeout、onUploadProgress 及 application/xml 类型;需直接传 file 对象而非 FormData,并注意编码、响应类型与组件卸载防护。

React上传XML文件 Ant Design的upload组件如何自定义请求

Ant Design Upload 组件默认不走 axiosfetch,而是用原生 XMLHttpRequest

这是关键前提:即使你项目里全局用了 axiosUploadcustomRequest 不显式覆盖,它就自己发请求,且无法携带 Authorization 头、无法设 timeout、无法监听 onUploadProgress —— 更别说上传 XML 文件时需要指定 Content-Type: application/xml

必须用 customRequest 替换默认上传逻辑

XML 文件本质是二进制 Blob,但服务端通常要求明确的 Content-Type 和原始文本结构。直接传 file 对象给 FormData 会自动加 boundary,不适合纯 XML 场景。

  • customRequest 函数接收 { file, onSuccess, onError, onProgress } 四个参数,必须手动调用它们来控制状态
  • 不要用 FormData.append('file', file) —— 这会让服务端收到 multipart 包裹体,而多数 XML 接口期望裸 XML 字符串或原始字节
  • 推荐读取为 text 后用 Blob 构造新对象,或直接用 file(如果服务端接受原始 application/xml
  • onProgress 只在 XMLHttpRequest.upload 上可用,fetch 原生不支持上传进度,所以这里仍建议用 XMLHttpRequest
customRequest: ({ file, onSuccess, onError, onProgress }) => {   const xhr = new XMLHttpRequest(); 

xhr.upload.onprogress = (e) => { if (e.lengthComputable) { onProgress({ percent: (e.loaded / e.total) * 100 }); } };

xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { onSuccess(xhr.response); } else { onError(new Error(Upload failed: ${xhr.status} ${xhr.statusText})); } };

xhr.onerror = () => onError(new Error('Network error'));

xhr.open('POST', '/api/upload-xml'); xhr.setRequestHeader('Content-Type', 'application/xml'); // 如果需要鉴权 // xhr.setRequestHeader('Authorization', Bearer ${token});

xhr.send(file); }

XML 文件内容校验和编码问题要提前处理

浏览器读取 XML 文件时,file.text() 会按 UTF-8 解码;但如果文件含 bom 或声明了 ,直接上传可能被服务端拒绝。稳妥做法是跳过解析,原样上传字节流 —— 这正是 xhr.send(file) 的优势。

  • 避免先 file.text().then(str => new Blob([str], ...)),这会二次编码,可能破坏原始声明
  • 若必须预览或校验内容,用 new FileReader().readAsText(file, 'UTF-8') 并捕获异常,但上传仍用原始 file 对象
  • 后端若返回非 jsON 响应(比如纯 XML 成功响应),注意 xhr.responseType 设置(如 'document'''),否则 xhr.response 可能为空

react 18 下注意 customRequest异步稳定性

如果上传中组件卸载,onSuccessonError 调用时可能触发 “Cannot update a component while rendering” 报错。需加简单清理机制:

  • customRequest 内部声明一个 isMounted = truexhr.onload 前判断
  • 或用 useRef 存储挂载状态,在 useEffect(() => () => { isMounted.current = false }, [])
  • 更轻量的做法:只确保 onSuccess/onError 是函数再调用,Ant Design 内部已做基础防护,但业务侧状态更新仍需自行守卫

XML 上传真正麻烦的不是格式本身,而是服务端对 Content-Type、编码、响应体类型的隐式约定 —— 动手前先 curl -v -H "Content-Type: application/xml" --data-binary @test.xml 验证通路,比调半天 React 逻辑更省时间。

text=ZqhQzanResources