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

Expo Go环境下PDF显示问题求助:两种实现方案均遇障碍

React Native 内嵌显示PDF的问题解决

项目环境

项目创建步骤:

  • npx create-expo-app my-app --template
  • 选择 Blank (TypeScript) 模板

遇到的具体问题

1. react-native-webview:PDF自动下载而非内嵌显示

即使服务器已配置支持inline内容处置,使用react-native-webview加载PDF时仍会触发下载,代码如下:

import React from 'react';
import { StyleSheet, View } from 'react-native';
import WebView from 'react-native-webview';

interface PDFViewerProps {
    uri: string;
}

const PDFViewer: React.FC<PDFViewerProps> = ({ uri }) => {
    return (
        <View style={styles.container}>
            <WebView
                originWhitelist={['*']}
                source={{
                    uri: `${uri}?inline=true`,
                    headers: {
                        'Content-Disposition': 'inline' 
                    }
                }}
                style={styles.webview}
            />
        </View>
    );
};

2. react-native-pdf:运行时报错 TypeError: Cannot read property 'fs' of undefined

切换到react-native-pdf后出现上述错误,代码如下:

import React from "react";
import { StyleSheet, View } from "react-native";
import Pdf from "react-native-pdf";

interface URLType {
  uri: string;
}

const PDFViewer: React.FC<URLType> = ({ uri }) => {
  return (
    <View style={styles.container}>
      <Pdf
        source={{ uri }}
        style={styles.pdf}
        onError={(error) => {
          console.error(error);
        }}
      />
    </View>
  );
};

问题原因及解决方案

针对react-native-webview的问题

移动端WebView内核对PDF的内嵌支持存在差异,即使设置Content-Disposition: inline,部分系统仍会优先触发下载。可以通过将PDF转为base64后加载来解决:

import React, { useState, useEffect } from 'react';
import { StyleSheet, View } from 'react-native';
import WebView from 'react-native-webview';

interface PDFViewerProps {
    uri: string;
}

const PDFViewer: React.FC<PDFViewerProps> = ({ uri }) => {
    const [pdfBase64, setPdfBase64] = useState<string | null>(null);

    useEffect(() => {
        const fetchAndConvertPDF = async () => {
            try {
                const response = await fetch(uri);
                const blob = await response.blob();
                const reader = new FileReader();
                reader.onloadend = () => setPdfBase64(reader.result as string);
                reader.readAsDataURL(blob);
            } catch (err) {
                console.error('获取PDF失败:', err);
            }
        };

        fetchAndConvertPDF();
    }, [uri]);

    if (!pdfBase64) return <View style={styles.container} />;

    return (
        <View style={styles.container}>
            <WebView
                originWhitelist={['*']}
                source={{ uri: pdfBase64 }}
                style={styles.webview}
            />
        </View>
    );
};

针对react-native-pdf的问题

react-native-pdf依赖原生文件系统模块,但Expo环境未预配置该依赖,导致fs未定义。推荐使用Expo官方支持的expo-pdf-reader替代,无需原生配置:

  1. 安装依赖:
npx expo install expo-pdf-reader
  1. 使用示例:
import React from 'react';
import { StyleSheet, View } from 'react-native';
import { PDFReader } from 'expo-pdf-reader';

interface PDFViewerProps {
    uri: string;
}

const PDFViewer: React.FC<PDFViewerProps> = ({ uri }) => {
    return (
        <View style={styles.container}>
            <PDFReader
                source={{ uri }}
                style={styles.pdf}
                onError={(err) => console.error(err)}
            />
        </View>
    );
};

若坚持使用react-native-pdf,需将Expo项目eject为裸React Native项目,再手动配置原生依赖,此方式复杂度高,不推荐。

最优方案推荐

对于Expo项目,expo-pdf-reader是最简便可靠的选择,官方维护、适配性好,无需复杂配置,直接安装即可实现PDF内嵌显示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 18:45:02