使用Expo Document Picker上传PDF至Cloudinary时JSON解析错误排查
排查Cloudinary上传PDF失败的问题
错误本质分析
SyntaxError: JSON Parse error: Unexpected token: < 说明你尝试把服务器返回的内容解析为JSON,但实际返回的是HTML(大概率是Cloudinary的错误提示页面)——核心问题是上传请求本身不符合Cloudinary的要求,导致服务器没有返回预期的JSON响应。
常见问题及修复方案
1. 未指定resource_type(最常见坑)
Cloudinary默认资源类型是image,上传PDF必须显式指定为raw,否则服务器会直接返回错误页面。
2. FormData构造错误
Expo DocumentPicker返回的是文件URI,直接传入FormData会导致解析失败,需要先转为Blob,且必须指定文件名:
// 选取文件后的处理逻辑 const result = await DocumentPicker.getDocumentAsync({ type: 'application/pdf' }); if (!result.canceled) { // 转换URI为Blob const response = await fetch(result.assets[0].uri); const blob = await response.blob(); const formData = new FormData(); // 三个参数:字段名、Blob对象、文件名(必须传,否则Cloudinary无法识别文件类型) formData.append('file', blob, result.assets[0].name); formData.append('upload_preset', '你的无签名上传预设'); formData.append('resource_type', 'raw'); // 关键参数 }
3. 请求头设置错误
不要手动设置Content-Type: multipart/form-data,fetch会自动根据FormData生成带边界标识的正确请求头,手动设置会导致服务器无法解析表单数据。
4. 上传预设配置问题
- 确认预设是无签名上传类型(如果用的是无签名流程)
- 再次检查预设的
Allowed file formats是否包含PDF(注意raw类型的允许列表单独设置) - 确保预设已启用
unsigned选项
5. 更简便的Expo专属上传方式
用expo-file-system的uploadAsync可以避免FormData的坑:
import { uploadAsync } from 'expo-file-system'; const uploadResult = await uploadAsync( 'https://api.cloudinary.com/v1_1/你的云名称/upload', result.assets[0].uri, { httpMethod: 'POST', uploadType: 'multipart', fieldName: 'file', parameters: { upload_preset: '你的无签名上传预设', resource_type: 'raw', }, } ); console.log(uploadResult.body);
调试技巧
捕获错误时先打印服务器返回的原始文本,不要直接解析JSON:
try { const res = await fetch('上传地址', { method: 'POST', body: formData }); // 先检查响应状态 if (!res.ok) { const errorText = await res.text(); console.log('Cloudinary错误详情:', errorText); // 这里会显示具体错误原因,比如预设无效、资源类型错误等 return; } const data = await res.json(); } catch (err) { console.log(err); }
内容的提问来源于stack exchange,提问作者JohnBradens
相关产品推荐
相关产品推荐

