React Native中API返回的PDF保存到本地文件系统出现0B问题如何解决
问题排查与修复方案
1. 关于base64有效性的判断
以SFRUU开头的base64字符串不是有效的PDF文件。
正常PDF文件的base64编码统一以JVBERi开头,解码后对应PDF标准头部标识%PDF-。你拿到的SFRUU开头的base64解码后为HTTP开头的明文,说明当前请求没有正确获取到PDF二进制流,拿到的是异常的响应报文。
2. 代码中的错误点
- 请求头配置错误
你在请求头中设置了Accept: 'application/json',明确告知接口需要返回JSON格式数据,接口不会返回PDF二进制流,需要修改为Accept: 'application/pdf'。 - 文件写入逻辑错误
调用RNFS.writeFile时传入的是Blob对象,同时指定编码为utf8,Blob对象无法直接按UTF8编码写入文件,会导致写入内容为空或者损坏。 - 冗余传参问题
你既初始化了FormData对象添加booking_id参数,又在RNFetchBlob.fetch的第四个参数中重复传入相同参数,属于冗余代码,可能导致请求参数异常。
3. 修正后的实现方案
推荐直接使用RNFetchBlob自带的文件写入能力,不需要额外转Blob,性能更高也不容易出错:
import { Platform } from 'react-native'; export const getParkingReciept = (bookingId) => { return async function (dispatch, getState) { try { const TOKEN = getState().Auth.token; // 先申请存储权限,再发起请求 const granted = await requestWritePermission(); if (!granted) { console.log("存储权限被拒绝"); return; } const path = `${RNFS.DownloadDirectoryPath}/${bookingId}.pdf`; // 发起请求直接写入文件 RNFetchBlob.config({ path: path, // 直接指定文件保存路径 fileCache: true, }) .fetch( 'POST', `${BASE_URL}parking-space/booking/receipt`, { 'Authorization': `Bearer ${TOKEN}`, 'Accept': 'application/pdf', // 正确设置接收PDF 'Content-Type': 'multipart/form-data' }, [{ name : 'booking_id', data: bookingId.toString()}] ) .then(async (res) => { console.log('PDF下载完成,保存路径:', res.path()); // 刷新媒体库 await RNFetchBlob.fs.scanFile([{ path : res.path(), mime : "application/pdf" }]); console.log('文件写入成功,已同步到系统文件'); }) .catch((error) => { console.log("下载PDF失败:", error); }); } catch (e) { console.log('请求异常:', e); } } } // 单独封装权限申请逻辑,适配不同Android版本 const requestWritePermission = async () => { // Android 13及以上废弃了WRITE_EXTERNAL_STORAGE权限,存公共下载目录无需额外权限 if (Platform.Version >= 33) { return true; } try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, { title: "存储权限申请", message: "需要存储权限才能保存停车凭证到本地", buttonNeutral: "稍后询问", buttonNegative: "取消", buttonPositive: "确定" } ); return granted === PermissionsAndroid.RESULTS.GRANTED; } catch (err) { console.warn('权限申请异常:', err); return false; } };
4. 额外注意事项
- 如果接口返回的PDF是base64编码的字符串,写入文件时需要指定编码为
base64,不要用utf8 - 测试时可以先把接口返回的base64字符串复制到本地base64转PDF工具验证内容是否正常,先排除接口返回异常的问题
内容的提问来源于stack exchange,提问作者Arjun
相关产品推荐
相关产品推荐

