Cordova iOS端文件下载后无法存储至公共目录问题咨询
我来帮你搞定这两个头疼的问题:路径双斜杠和文件存到用户能找到的公共目录。
1. 修复路径中的双斜杠问题
从日志里的download//Word1.DOC就能看出问题根源:cordova.file.documentsDirectory本身就以斜杠/结尾,而你初始化插件时设置的folder: 'download',插件会自动在这个文件夹名后加斜杠,两者一拼接就出现了重复的斜杠。
解决起来很简单,手动移除storage_location末尾的斜杠就行:
if (ionic.Platform.isIOS()) { // 移除路径末尾的斜杠,避免拼接时产生双斜杠 storage_location = cordova.file.documentsDirectory.replace(/\/$/, ''); } else if (ionic.Platform.isAndroid()) { storage_location = 'file:///storage/emulated/0/'; }
这样插件生成的路径就会变成/Documents/download/Word1.DOC,双斜杠的问题就彻底解决了。
2. 让文件保存到iOS公共可访问的目录
你现在的文件存在应用私有目录里,用户自然找不到。要让文件能在Files应用里被看到,有两种可靠的方式:
方式一:共享应用的Documents目录(最简单)
通过配置Info.plist,让应用的私有Documents目录在Files应用中显示。在你的config.xml里添加以下配置:
<platform name="ios"> <!-- 开启文件共享,让应用目录出现在Files中 --> <config-file parent="UIFileSharingEnabled" platform="ios" target="*-Info.plist"> <true/> </config-file> <!-- 支持在原地打开文件 --> <config-file parent="LSSupportsOpeningDocumentsInPlace" platform="ios" target="*-Info.plist"> <true/> </config-file> </platform>
配置完成后,用户打开Files应用,就能在「On My [设备名称]」下找到你的应用文件夹,里面的download子目录和下载的文件都会清晰显示出来。
方式二:保存到系统公共Downloads目录(iOS 11+)
如果你想直接把文件存到系统级的Downloads目录,可以使用cordova.file.downloadsDirectory,但注意这个路径只支持iOS 11及以上版本。
首先修改你的存储路径:
if (ionic.Platform.isIOS()) { // 使用系统公共Downloads目录,移除末尾斜杠避免双斜杠 storage_location = cordova.file.downloadsDirectory.replace(/\/$/, ''); }
然后在config.xml中添加权限说明(iOS要求必须说明访问权限的用途):
<platform name="ios"> <config-file parent="NSFileProviderDomainUsageDescription" platform="ios" target="*-Info.plist"> <string>需要访问Downloads目录以保存您下载的文件</string> </config-file> </platform>
这样文件就会被保存到系统的Downloads目录,用户可以直接在Files应用的「Downloads」文件夹中找到它们。
3. 验证下载结果
为了确保文件确实保存成功,你可以在下载完成的回调里添加文件存在性检查:
let downloaded = function(event) { setTimeout(function() { $scope.endStatus(fileInfo.cfID); // 检查文件是否存在并打印路径 const fullPath = `${storage_location}/download/${newFileName}`; window.resolveLocalFileSystemURL(fullPath, function(fileEntry) { console.log('文件已成功保存到:', fileEntry.nativeURL); }, function(error) { console.error('文件保存失败:', error); } ); event.target.removeEventListener(event.name, downloaded); }, 5000); }
内容的提问来源于stack exchange,提问作者rolinger

