Expo React Native如何从Node.js服务器下载PDF/Excel到本地?
Expo React Native 从Node.js服务器保存Base64/二进制文件到本地方案
针对你需要调用Node.js接口获取Base64或二进制数据并保存到设备本地的需求,以下是基于Expo官方API的可行方案,无需依赖rn-fetch-blob这类需要原生配置的库:
方案1:处理Base64格式的文件数据
如果你的Node.js接口返回Base64编码的文件内容(比如PDF/Excel),可以按以下步骤实现:
- 调用接口获取Base64字符串
- 使用
expo-file-system的writeAsStringAsync方法将Base64数据写入本地文件 - 获取本地文件URI后,即可用于分享或其他操作
代码示例
修改你的handleDownload函数为以下逻辑:
async function handleDownload() { try { // 调用Node.js接口,获取Base64数据 const response = await fetch('你的Node.js接口地址', { method: 'POST', // 或GET,根据接口定义调整 headers: { 'Content-Type': 'application/json', // 如有需要,添加认证头如Authorization }, body: JSON.stringify({ /* 接口请求参数 */ }) }); if (!response.ok) { throw new Error('接口请求失败'); } const data = await response.json(); // 假设接口返回{ base64Data: "...", fileName: "文件名称.pdf" } const base64Data = data.base64Data; const fileName = data.fileName; // 定义本地文件路径 const fileUri = FileSystem.documentDirectory + fileName; // 将Base64数据写入文件,指定编码为base64 await FileSystem.writeAsStringAsync(fileUri, base64Data, { encoding: FileSystem.EncodingType.Base64 }); console.log('文件保存成功:', fileUri); setDocument(fileUri); } catch (e) { console.error('保存失败:', e); Alert.alert('错误', '文件保存失败,请重试'); } }
方案2:处理二进制格式的文件数据
如果接口直接返回二进制数据流(比如设置Content-Disposition头的文件下载接口),可以通过以下方式处理:
- 调用接口时获取二进制数据,转换为Base64编码
- 再写入本地文件(和方案1的写入步骤一致)
代码示例
async function handleDownload() { try { const response = await fetch('你的Node.js二进制文件接口地址', { method: 'GET', // 通常二进制下载用GET headers: { // 按需添加请求头 } }); if (!response.ok) { throw new Error('接口请求失败'); } // 将二进制Blob转换为Base64 const blob = await response.blob(); const base64Data = await new Promise((resolve) => { const reader = new FileReader(); reader.onloadend = () => resolve(reader.result.split(',')[1]); reader.readAsDataURL(blob); }); // 从响应头获取文件名(如果接口返回的话) const contentDisposition = response.headers.get('Content-Disposition'); let fileName = 'downloaded_file.pdf'; if (contentDisposition) { const matches = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/); if (matches != null && matches[1]) { fileName = matches[1].replace(/['"]/g, ''); } } const fileUri = FileSystem.documentDirectory + fileName; await FileSystem.writeAsStringAsync(fileUri, base64Data, { encoding: FileSystem.EncodingType.Base64 }); console.log('文件保存成功:', fileUri); setDocument(fileUri); } catch (e) { console.error('保存失败:', e); Alert.alert('错误', '文件保存失败,请重试'); } }
关键注意事项
- Node.js接口配置:如果返回Base64,确保接口返回的Base64字符串不包含前缀(如
data:application/pdf;base64,),如果包含,需要先截取后面的部分;如果是二进制接口,确保响应头的Content-Type设置正确(比如PDF为application/pdf,Excel为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)。 - 文件权限:Expo的
documentDirectory是应用私有目录,无需额外权限即可读写;如果需要保存到公共目录(如相册、下载文件夹),需要使用expo-media-library或expo-document-picker相关API,并申请对应权限。 - 进度监听:如果需要监听二进制下载进度,可以使用
expo-file-system的createDownloadResumable直接下载接口返回的文件(如果接口是直接可下载的文件URL),但如果是需要带参数的接口,可能需要先获取临时下载链接再使用该方法。
内容的提问来源于stack exchange,提问作者Saroj
相关产品推荐
相关产品推荐

