You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Expo React Native使用expo-file-system下载PDF格式无效如何解决

PDF下载后格式无效问题修复

核心错误原因

  • axios请求PDF接口时未指定二进制响应类型,默认将PDF二进制流按UTF-8文本解析,原始数据被不可逆损坏
  • 数据转码逻辑冗余错误:错误将接口返回的文本内容按base64解析后再次转base64,写入文件的内容不符合PDF格式规范
  • 创建文件时未给文件名添加.pdf后缀,部分系统PDF阅读器无法正确识别文件类型

修复步骤

  1. 给axios请求添加responseType: 'arraybuffer'配置,确保拿到未被转码的原始PDF二进制数据
  2. 移除无效的重复转码逻辑,直接将ArrayBuffer格式的响应数据转成base64字符串
  3. 创建文件时给文件名追加.pdf后缀,兼容系统文件识别规则

修正后代码

修正后的grabPdf方法

const grabPdf = async () => {
    axiosConfig.defaults.headers.common['Authorization'] = `Bearer ${user.token}`;
    const response = await axiosConfig('/user/invoice/C0F19758-0001/247', {
        // 关键配置:指定响应类型为二进制数组,避免文本转码损坏PDF
        responseType: 'arraybuffer'
    }).catch(error => {
        console.log('请求PDF失败: ', error.response?.data || error.message);
        alert('下载失败: ' + error.message);
    });

    // 正确将二进制数据转换为base64
    const pdfBuffer = Buffer.from(response.data);
    return pdfBuffer.toString('base64');
}

修正后的文件创建逻辑

在downloadFile方法中修改createFileAsync调用,补全文件后缀:

await StorageAccessFramework.createFileAsync(
    permissions.directoryUri,
    // 文件名追加.pdf后缀
    `inv${payment.invoice_number}.pdf`,
    'application/pdf'
).then(async(uri) => {
    await FileSystem.writeAsStringAsync(uri, pdf, { encoding: FileSystem.EncodingType.Base64 });
    Alert.alert('Success', 'Successfully downloaded');
}).catch((e) => {
    console.log('写入文件失败: ', e);
    alert('保存文件失败');
});

有效性校验

修复后可以在返回base64字符串前打印前10个字符,合法PDF文件的base64开头固定为JVBERi0xLj(对应PDF文件头标识%PDF-1.x),如果开头不符合该特征,说明接口返回的数据本身有问题。

内容的提问来源于stack exchange,提问作者Vic Andam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:27:16