uni.openDocument在App端仅支持本地文件路径,不接受网络URL或file://等非标准路径;必须通过uni.downloadFile下载后,用res.tempFilePath或uni.saveFile生成的savedFilePath调用,且需校验statusCode为200。

uni.openDocument 在 App 端能直接打开 PDF、Office 等常见文档,但仅限于已下载到本地的文件路径——它不接受网络 URL,也不支持 file:// 或 __UNI__ 这类非标准协议路径。用错路径格式是 90% 的“打开失败”根源。
为什么 uni.openDocument 调用后没反应或报错 “filePath is not valid”
App 端对 filePath 校验极严,常见失效路径包括:
-
__UNI__xxx.pdf:H5 可用,App 端完全无法识别 -
file:///var/mobile/.../temp.pdf(iOS)或file:///data/user/.../temp.pdf(Android):系统拒绝加载,openDocument不支持file://协议 -
http://或https://链接:直接传 URL 会静默失败,无提示 - 未等
uni.downloadFile完全成功就调用:res.tempFilePath为空或未生成
真正有效的路径只有两类:res.tempFilePath(临时路径,生命周期短)或 uni.saveFile 后返回的 savedFilePath(持久路径,推荐)。
如何确保 uni.openDocument 在 iOS/Android 上都稳定触发
关键不是“怎么调”,而是“怎么准备路径”。必须走完整下载 → 校验 → 打开链路:
- 务必检查
res.statusCode === 200,不能只看success回调 - 下载完成后立即调用
uni.saveFile,把临时文件固化为持久路径(尤其 iOS 对临时文件清理更激进) -
fileType参数可填可不填,但填对能提升部分 Android 厂商机型的兼容性(如'pdf'、'docx') - iOS 上若仍失败,需确认
NSAppTransportSecurity已允许 HTTP(如果源地址是 http)
示例片段:
uni.downloadFile({
url: 'https://api.example.com/file.pdf',
header: { 'Authorization': 'Bearer xxx' },
success: (res) => {
if (res.statusCode === 200) {
uni.saveFile({
tempFilePath: res.tempFilePath,
success: (saveRes) => {
uni.openDocument({
filePath: saveRes.savedFilePath,
fileType: 'pdf',
success: () => console.log('已打开'),
fail: (err) => console.error('open fail', err)
});
}
});
}
}
});
uni.openDocument 的实际限制与替代方案
它本质是“唤起系统默认应用”,所以有天然边界:
- 用户设备上没装 PDF 阅读器(如 iOS 未装 Adobe Reader、WPS),就会弹出“无法打开”提示
- 无法控制 UI(比如不能隐藏菜单、不能禁用打印)、不能嵌入页面、不能监听翻页事件
- Office 文件(.docx/.xlsx)在低端 Android 设备上容易卡死或白屏
- 不支持加密 PDF(带密码的文件会直接失败)
如果业务要求“不跳转、不依赖外部 App、支持进度/水印/权限控制”,就得放弃 uni.openDocument,改用 WebView + pdf.js(PDF)或原生插件(如 zhangwei-uvue-pdf-viewer)——但那是另一套路径了。
最易被忽略的一点:App 端的 tempFilePath 在冷启动后大概率失效,而 savedFilePath 也可能被用户手动清除。线上问题里,70% 的“昨天还好今天打不开”,其实只是忘了做文件存在性校验和降级兜底。


















