React Native如何上传XML文件 fetch和FormData的使用

React Native上传XML必须用FormData包装Blob,不可传字符串或手动设Content-Type;需base64编码后fetch生成Blob,append时字段名须与后端严格一致。

React Native中XML文件上传必须用FormData,不能直接传字符串

React Native的fetch不支持直接发送原始XML文本(如text/xmlapplication/xml)作为请求体——即使设置了Content-Type,原

生模块会忽略该头,实际仍按multipart/form-data处理。唯一可靠方式是把XML内容包装进FormData对象,并以BlobFile形式附加。

XML内容需转为Blob再append进FormData

React Native没有全局File构造函数,也不能直接用new Blob([xmlString])(iOS/Android对Blob支持不一致)。正确做法是:先用base64编码XML字符串,再通过fetchblob()方法生成可append的Blob实例。

  • 不要用FormData.append('file', xmlString)——这会传成纯文本字段,后端收不到标准文件流
  • 不要手动设置Content-Type: application/xml——FormData会自动生成边界头,覆盖你的设置
  • XML含中文或特殊字符时,确保原始字符串已UTF-8编码(通常JS字符串默认满足)
const xmlString = `123`;
const blob = await (await fetch(`data:application/xml;base64,${btoa(xmlString)}`)).blob();

const formData = new FormData();
formData.append('xml_file', blob, 'data.xml'); // 第三个参数是文件名,影响Content-Disposition

fetch配置要点:禁用header、用原生body、处理超时与错误

FormData对象必须直接作为fetchbody,且不能设置Content-Type头——否则React Native会报Network request failed或触发iOS的NSURLErrorDomain -1005错误。

  • headers字段应完全省略,或只保留非Content-Type相关头(如Authorization
  • 安卓需确认android:usesCleartextTraffic="true"(若传HTTP);iOS需在Info.plistNSAppTransportSecurity例外(若非HTTPS)
  • 上传大XML(>5MB)建议加timeout逻辑,React Native原生fetch不支持timeout,需用AbortController或封装Promise.race
const response = await fetch('https://api.example.com/upload', {
  method: 'POST',
  body: formData,
  headers: {
    // ❌ 不要写 'Content-Type': 'multipart/form-data'
    'Authorization': 'Bearer xyz'
  }
});

后端接收时注意字段名和文件名匹配

后端框架(如Express + multer、Django、Spring Boot)依赖FormData中的key(即append第一个参数)来定位文件。如果前端写formData.append('xml_file', blob, 'data.xml'),后端就必须用xml_file这个字段名取文件,而不是靠Content-Type或文件扩展名。

  • Node.js + multer示例:需配置multer({ storage: ... }).single('xml_file')
  • Django视图里用request.FILES.get('xml_file'),不是request.FILES.get('data.xml')
  • 如果后端返回400 Bad Request且提示“no file part”,大概率是字段名不一致
React Native上传XML真正卡点不在语法,而在Blob生成路径和FormData字段名与后端的严格对应——漏掉btoa、错写append键名、或手加Content-Type头,都会导致静默失败。