You need to enable JavaScript to run this app. React Native中API返回的PDF保存到本地文件系统出现0B问题如何解决
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 05:45:04