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

React Native多文件选择器无法上传文件至服务器问题排查

React Native多文件上传后端无法接收的解决方案

问题根源

你的代码存在两个关键问题导致后端无法接收文件:

  • 多文件的FormData添加方式错误:直接将整个文件数组append到documents[]字段,后端无法解析这种格式
  • 文件URI处理不规范:部分平台(如Android)的原生URI无法被FormData正确识别

修正后的代码实现

1. 调整文件选择逻辑(确保URI有效性)

const selectMyFiles = async () => {
    try {
      const results = await DocumentPicker.pick({
        copyTo: 'documentDirectory',
        allowMultiSelection: true,
        type: [
          DocumentPicker.types.pdf,
          DocumentPicker.types.docx,
          DocumentPicker.types.images,
        ],
      });
      const validDocuments = [];
      const newSelectedFiles = [...selectedFiles];
      
      for (const result of results) {
        const {name, uri, size, type, fileCopyUri} = result;
        const fileSizeMB = size / 1048576;
        
        if (fileSizeMB > 2) {
          Alert.alert('文件大小超限', '单文件最大不能超过2MB', [
            {text: '重新选择', onPress: () => selectOneFile(), style: 'cancel'},
          ]);
          return;
        }
        
        // 优先使用fileCopyUri(已复制到app可访问目录,避免权限问题)
        const fileUri = Platform.OS === 'android' ? `file://${fileCopyUri}` : fileCopyUri;
        
        const fileItem = {
          name,
          uri: fileUri,
          size,
          type,
          fileCopyUri
        };
        
        newSelectedFiles.push(fileItem);
        validDocuments.push(fileItem);
      }

      setSelectedFiles(newSelectedFiles);
      setFilesInAction(validDocuments);
      setModalValue(false);
 
    } catch (err) {
      if (DocumentPicker.isCancel(err)) {
        alert('已取消文件选择');
      } else {
        alert('文件选择出错: ' + err);
        throw err;
      }
    }
  };

2. 修正FormData文件添加逻辑

const onPressSubmit = () => {
    const formData = new FormData();
    
    // 添加普通字段
    formData.append('remarks', inputContactState);
    formData.append('category_id', categoryId);
    
    // 逐个添加文件,后端若期望数组形式则用documents[]作为键名
    filesInAction.forEach(file => {
      formData.append('documents[]', {
        uri: file.uri,
        name: file.name,
        type: file.type || 'application/octet-stream' // 兜底类型,避免类型缺失
      });
    });
    
    dispatch(contactComplaintAction(formData));
  };

额外注意事项

  • 请求头配置:确保你的请求拦截器或API封装中,不要手动设置Content-Type为application/json,应该让系统自动处理为multipart/form-data(带boundary)。如果使用axios,需设置headers: {'Content-Type': 'multipart/form-data'}但不要手动指定boundary。
  • 后端字段匹配:确认后端接收文件的字段名是documents[]还是documents,若后端用documents则直接formData.append('documents', ...)即可。
  • Android权限:确保已在AndroidManifest.xml中添加文件读取权限,Android 13+需添加READ_MEDIA_IMAGES、READ_MEDIA_DOCUMENTS等权限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 15:48:22