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

React Native图片转multipart/form-data调用OCR API遇问题求助

React Native 将ImagePicker图片转为multipart/form-data调用OCR API解决方案

针对你遇到的问题,核心是React Native(尤其是Expo环境)中本地文件URI无法直接被FormData正确解析,导致API请求失败。以下是经过验证的解决步骤和代码示例:

关键方案:手动读取文件为Blob构造FormData

Expo环境下推荐使用expo-file-system读取本地文件内容,转成Blob后再构造FormData,这是最可靠的方式。

步骤1:安装依赖

npx expo install expo-file-system

步骤2:完整代码示例(用axios)

import * as ImagePicker from 'expo-image-picker';
import * as FileSystem from 'expo-file-system';
import axios from 'axios';

// 上传图片到OCR API的函数
const uploadToOCR = async (imageUri, fileName, mimeType) => {
  try {
    // 验证文件存在
    const fileInfo = await FileSystem.getInfoAsync(imageUri);
    if (!fileInfo.exists) throw new Error('目标图片文件不存在');

    // 将本地文件转成Base64,再转成Blob
    const base64Content = await FileSystem.readAsStringAsync(imageUri, {
      encoding: FileSystem.EncodingType.Base64,
    });
    const blob = new Blob(
      [Uint8Array.from(atob(base64Content), char => char.charCodeAt(0))],
      { type: mimeType }
    );

    // 构造multipart/form-data
    const formData = new FormData();
    formData.append('file', blob, {
      filename: fileName,
      type: mimeType,
    });

    // 发送API请求
    const response = await axios.post(
      'https://ocr-extract-text.p.rapidapi.com/api/v1/ocr/image',
      formData,
      {
        headers: {
          'X-RapidAPI-Key': '你的RapidAPI密钥',
          'X-RapidAPI-Host': 'ocr-extract-text.p.rapidapi.com',
          // 无需手动设置Content-Type: multipart/form-data,axios会自动处理boundary
        },
      }
    );

    console.log('OCR识别结果:', response.data);
    return response.data;
  } catch (error) {
    console.error('上传失败详情:', error.response?.data || error.message);
    throw error;
  }
};

// 调用ImagePicker并上传的示例
const pickAndUploadImage = async () => {
  const pickResult = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    allowsEditing: false,
    quality: 0.8,
  });

  if (!pickResult.canceled) {
    const image = pickResult.assets[0];
    await uploadToOCR(image.uri, image.fileName, image.mimeType);
  }
};

步骤3:用Fetch的替代实现

如果不想用axios,也可以用原生Fetch:

const uploadWithFetch = async (imageUri, fileName, mimeType) => {
  const base64Content = await FileSystem.readAsStringAsync(imageUri, {
    encoding: FileSystem.EncodingType.Base64,
  });
  const blob = new Blob(
    [Uint8Array.from(atob(base64Content), char => char.charCodeAt(0))],
    { type: mimeType }
  );

  const formData = new FormData();
  formData.append('file', blob, fileName);

  const response = await fetch(
    'https://ocr-extract-text.p.rapidapi.com/api/v1/ocr/image',
    {
      method: 'POST',
      headers: {
        'X-RapidAPI-Key': '你的RapidAPI密钥',
        'X-RapidAPI-Host': 'ocr-extract-text.p.rapidapi.com',
        // Fetch会自动生成正确的multipart/form-data头部和boundary,不要手动设置
      },
      body: formData,
    }
  );

  if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`);
  const data = await response.json();
  console.log('OCR结果:', data);
  return data;
};

常见问题排查

  • 权限问题:确保app.json中配置了网络权限:
    "expo": {
      "android": {
        "permissions": ["INTERNET"]
      },
      "ios": {
        "infoPlist": {
          "NSAppTransportSecurity": {
            "NSAllowsArbitraryLoads": true
          }
        }
      }
    }
    
  • 头部错误:必须携带X-RapidAPI-Key和X-RapidAPI-Host,这两个是RapidAPI接口的必填项,要和Postman中的配置完全一致
  • Blob验证:可以打印blob.size,和ImagePicker返回的fileSize对比,确认文件读取完整
  • 端点地址:确认API端点和Postman中使用的完全一致,注意是否有路径拼写错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:07:04