如何在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
相关产品推荐
相关产品推荐

