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
相关产品推荐
相关产品推荐

