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

如何在Android端通过React Native的WebView组件实现PDF文件下载?

React Native WebView 实现 Android 端文件下载(点击 href 链接触发)

核心思路

拦截WebView中的链接请求,识别出文件类型的URL后,阻止WebView默认加载行为,转而调用React Native的下载能力完成文件下载。

步骤实现

1. 修改WebView组件,添加请求拦截属性

更新你的WebView代码,新增onShouldStartLoadWithRequest属性捕获所有页面请求:

<WebView
  ref={webViewRef}
  style={styles.webv}
  source={{
    uri: Domain_URL, // 替换为实际业务域名
  }}
  onMessage={onWebViewMessage}
  onError={onWebViewError}
  onLoadStart={onWebViewLoadStart}
  onLoad={onWebViewLoadEnd}
  javaScriptEnabled
  domStorageEnabled
  setBuiltInZoomControls={false}
  // 新增:拦截请求判断是否为文件下载链接
  onShouldStartLoadWithRequest={handleShouldStartLoad}
/>

2. 编写请求拦截逻辑

实现handleShouldStartLoad函数,判断请求URL是否为需要下载的文件类型:

const handleShouldStartLoad = (request) => {
  const url = request.url;
  // 自定义需要触发下载的文件后缀列表
  const downloadFileExtensions = ['.pdf', '.docx', '.doc', '.zip', '.rar', '.xlsx', '.xls', '.apk'];
  
  // 判断当前请求是否指向可下载文件
  const isDownloadableFile = downloadFileExtensions.some(ext => url.includes(ext));
  
  if (isDownloadableFile) {
    // 触发下载逻辑
    downloadFile(url);
    // 返回false,阻止WebView加载该链接
    return false;
  }
  
  // 返回true,允许WebView正常加载页面链接
  return true;
};

3. 实现文件下载功能

使用react-native-fs库完成下载逻辑(RN层即可实现,无需原生开发):

安装依赖
npm install react-native-fs --save
# 或使用yarn
yarn add react-native-fs
编写下载函数
import RNFS from 'react-native-fs';

const downloadFile = async (fileUrl) => {
  try {
    // 从URL中提取文件名
    const fileName = fileUrl.split('/').pop();
    // Android外部存储目录(用户可直接访问)
    const savePath = `${RNFS.ExternalDirectoryPath}/${fileName}`;
    
    // 初始化下载任务
    const downloadTask = RNFS.downloadFile({
      fromUrl: fileUrl,
      toFile: savePath,
      progressDivider: 1, // 每1%触发一次进度回调
      progress: (progressData) => {
        const downloadProgress = (progressData.bytesWritten / progressData.contentLength) * 100;
        console.log(`下载进度:${Math.floor(downloadProgress)}%`);
        // 可在此处更新UI显示下载进度
      },
    });

    // 等待下载完成
    const downloadResult = await downloadTask.promise;
    
    if (downloadResult.statusCode === 200) {
      console.log(`文件下载完成,路径:${savePath}`);
      // 可在此处添加下载成功的用户提示(如Toast)
    } else {
      console.error(`下载失败,状态码:${downloadResult.statusCode}`);
    }
  } catch (error) {
    console.error('下载出错:', error);
  }
};

4. 配置Android权限

在android/app/src/main/AndroidManifest.xml中添加必要权限:

<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Android 13以下存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<!-- Android 13+ 媒体访问权限 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />

注意事项

  • 若页面中存在动态生成或JS跳转的文件链接,需确保onShouldStartLoadWithRequest能捕获到对应请求;
  • 如需支持更多文件类型,直接在downloadFileExtensions数组中添加对应后缀即可;
  • 下载完成后可结合RN通知组件(如react-native-push-notification)提示用户文件已就绪。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 20:30:48