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

Expo React Native从API获取PDF并在设备默认浏览器显示的问题

解决方案(无需eject Expo)

核心思路:手动修正API返回的Blob类型,将其转换为PDF格式后保存到本地,再通过Expo提供的可共享URI在默认浏览器中打开。

步骤1:正确获取并转换API响应

API返回的是PDF数据但Content-Type被错误标记为application/json,需要手动将响应Blob转换为PDF类型:

import * as FileSystem from 'expo-file-system';
import * as Linking from 'expo-linking';

const fetchAndOpenPDF = async () => {
  try {
    const res = await fetch('API_URL', {
      method: 'GET',
      headers: {
        Authorization: 'AUTH_TOKEN',
        // GET请求无需设置content-type,服务器返回的是PDF二进制数据
      },
    });

    if (!res.ok) throw new Error('API请求失败');

    // 将响应转为Blob,并手动指定正确的PDF MIME类型
    const rawBlob = await res.blob();
    const pdfBlob = new Blob([rawBlob], { type: 'application/pdf' });

    // 步骤2:将Blob转为Base64并保存到本地
    const reader = new FileReader();
    reader.readAsDataURL(pdfBlob);
    
    reader.onloadend = async () => {
      // 去掉Data URL前缀,只保留Base64数据
      const base64Data = reader.result.split(',')[1];
      // 生成缓存目录下的PDF文件路径
      const fileUri = `${FileSystem.cacheDirectory}temp.pdf`;

      // 写入Base64数据到文件
      await FileSystem.writeAsStringAsync(fileUri, base64Data, {
        encoding: FileSystem.EncodingType.Base64,
      });

      // 步骤3:获取可被外部应用访问的Content URI
      // iOS沙盒限制,直接用file://路径无法被浏览器访问
      const contentUri = await FileSystem.getContentUriAsync(fileUri);

      // 在默认浏览器中打开PDF
      await Linking.openURL(contentUri);

      // 可选:用完后删除临时文件,节省存储空间
      setTimeout(() => {
        FileSystem.deleteAsync(fileUri).catch(err => console.warn('删除临时文件失败:', err));
      }, 5000);
    };
  } catch (err) {
    console.error('处理PDF失败:', err);
  }
};

错误原因分析

  1. FileSystem.downloadAsync失败:该方法无法自定义请求头(如Authorization),因此无法通过API的权限校验,必须用fetch手动获取数据。
  2. 直接打开file://路径报错:iOS沙盒机制禁止外部应用(如浏览器)直接访问App私有目录的file路径,必须使用getContentUriAsync生成的content://协议URI。
  3. writeAsStringAsync崩溃:直接写入Blob的原始字符串会导致编码错误,必须将Blob转换为Base64格式后再写入。

注意事项

  • 确保已安装依赖:expo install expo-file-system expo-linking
  • 必须在真机上测试,模拟器的文件系统权限和行为与真机存在差异
  • 临时文件建议在使用后删除,避免占用设备存储空间

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 08:42:40