React Native WebView中如何下载Base64编码链接的文件
解决WebView中Base64编码下载链接的拦截与文件保存问题
1. 启用WebView请求拦截
取消注释onShouldStartLoadWithRequest方法,这是拦截WebView跳转请求的核心入口,用于捕获目标下载链接。修改后的WebView核心配置如下:
<WebView style={styles.WebView} useWebKit={true} source={{ uri: url }} javaScriptEnabled={true} domStorageEnabled={true} decelerationRate="normal" startInLoadingState={true} originWhitelist={['http://*','https://*', 'git://*',"file://"]} mixedContentMode="compatibility" injectedJavaScript={INJECTEDJAVASCRIPT} mediaPlaybackRequiresUserAction={false} allowsInlineMediaPlayback={true} allowFileAccess={true} allowUniversalAccessFromFileURLs={true} onNavigationStateChange={(newNavState) => { console.log('TEST'); }} onShouldStartLoadWithRequest={this.handleDownloadRequest} // 启用拦截方法 />
2. 编写拦截与Base64解码逻辑
在handleDownloadRequest方法中识别带download属性的链接,提取并解码Base64内容:
handleDownloadRequest = (request) => { // 判断是否为点击触发的下载链接(可根据实际场景调整识别规则) const isDownloadLink = request.navigationType === 'click' && request.download; if (isDownloadLink) { const base64Str = request.url; try { let decodedData, mimeType, fileName; // 处理data URI格式的Base64链接(如data:image/png;base64,xxxx) if (base64Str.startsWith('data:')) { const [metaPart, dataPart] = base64Str.split(','); mimeType = metaPart.match(/data:(.*?);/)[1]; decodedData = atob(dataPart); fileName = request.download || `file.${mimeType.split('/')[1]}`; } else { // 处理纯Base64编码的文件内容 decodedData = atob(base64Str); fileName = request.download || 'downloaded_file'; mimeType = 'application/octet-stream'; } // 调用保存方法 this.saveFileToDevice(decodedData, fileName, mimeType); return false; // 阻止WebView默认跳转,避免报错 } catch (error) { console.error('Base64解码失败:', error); return true; // 解码失败时允许默认处理 } } return true; // 非下载链接正常跳转 };
3. 实现文件保存到设备
使用react-native-fs库处理文件存储,步骤如下:
安装依赖
npm install react-native-fs --save
编写保存方法
import RNFS from 'react-native-fs'; import { Alert } from 'react-native'; saveFileToDevice = async (decodedData, fileName, mimeType) => { try { // 获取设备文档目录路径 const destPath = `${RNFS.DocumentDirectoryPath}/${fileName}`; // 将解码后的字符串转为二进制数组 const bytes = new Uint8Array(decodedData.length); for (let i = 0; i < decodedData.length; i++) { bytes[i] = decodedData.charCodeAt(i); } // 写入文件 await RNFS.writeFile(destPath, bytes, 'base64'); Alert.alert('保存成功', `文件已保存:${fileName}`); } catch (error) { console.error('文件保存失败:', error); Alert.alert('保存失败', '无法保存文件,请检查权限设置'); } };
4. 配置设备权限
- Android:在
AndroidManifest.xml中添加权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- Android 10+ 需添加以下配置到application标签内 --> android:requestLegacyExternalStorage="true" - iOS:在
Info.plist中添加权限描述:<key>NSDocumentFolderUsageDescription</key> <string>需要访问文档目录以保存下载文件</string>
内容的提问来源于stack exchange,提问作者Zuhair
相关产品推荐
相关产品推荐

