使用apollo-upload-client上传文件时App崩溃及Blob上传异常
问题解决:React Native 结合 Apollo 上传文件的两类异常处理
一、解决okhttp3.internal.Util类找不到问题
1. 统一OkHttp版本
React Native 0.68.1自带的OkHttp版本可能与apollo-upload-client依赖版本冲突,导致内部类缺失。在项目根目录的android/build.gradle中强制指定兼容版本:
allprojects { configurations.all { resolutionStrategy.force 'com.squareup.okhttp3:okhttp:4.9.3' resolutionStrategy.force 'com.squareup.okhttp3:logging-interceptor:4.9.3' } }
2. 修复ProGuard混淆规则
若开启代码混淆,需确保ProGuard未移除OkHttp内部类。在android/app/proguard-rules.pro中添加:
-keep class okhttp3.** { *; } -keep interface okhttp3.** { *; } -dontwarn okhttp3.internal.**
3. 清理缓存重建项目
执行命令清理RN和Android构建缓存:
# 重置RN缓存 npx react-native start --reset-cache # 清理Android构建文件 cd android && ./gradlew clean && cd ..
二、解决Blob上传后端接收file为null问题
1. 替换RN原生Blob实现,适配Apollo上传逻辑
RN的Blob与Web端实现存在差异,apollo-upload-client对其支持有限。使用react-native-file-access读取文件并构建兼容的上传对象:
先安装依赖:
npm install react-native-file-access
修改上传逻辑:
import { FileSystem } from 'react-native-file-access'; // ... 其他代码 const uploadFile = async (fileUri, fileName, mimeType) => { // 读取文件为ArrayBuffer const base64Data = await FileSystem.readFile(fileUri, 'base64'); const arrayBuffer = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0)); // 构建Apollo可识别的文件对象 const file = { uri: Platform.OS === 'android' && !fileUri.startsWith('file://') ? `file://${fileUri}` : fileUri, name: fileName, type: mimeType, blob: new Blob([arrayBuffer], { type: mimeType }) }; try { const { data } = await uploadImageMutation({ variables: { file } }); console.log('Upload response:', data); } catch (error) { console.error('Upload error:', error); } };
2. 检查Apollo客户端配置
确保使用createUploadLink替代普通createHttpLink,开启文件上传支持:
import { ApolloClient, InMemoryCache } from '@apollo/client'; import { createUploadLink } from 'apollo-upload-client'; const client = new ApolloClient({ link: createUploadLink({ uri: '你的后端GraphQL地址', headers: { // 自定义请求头,如Authorization } }), cache: new InMemoryCache(), });
3. 抓包对比请求差异
用Charles或Fiddler抓取RN上传请求,与Postman请求对比:
- 检查FormData的字段名是否与后端接收参数
file一致 - 验证Content-Type是否为
multipart/form-data且包含正确的边界标识
额外排查建议
- 确认后端GraphQL解析器已正确配置文件上传(如使用
graphql-upload) - 尝试降级
apollo-upload-client至v10.x版本,适配RN 0.68的旧环境
内容的提问来源于stack exchange,提问作者daniel meyer
相关产品推荐
相关产品推荐

