【发布时间】:2019-10-31 19:21:56
【问题描述】:
我最近将我的 Ionic 4 Angular 应用程序发布为网络应用程序和原生 Android 应用程序。
在原生 Android 应用中,一切正常,除了保存下载的文件。
要下载和保存文件,我一直使用file-saver npm 包,如下所示(这是我每次必须下载东西时调用的共享服务,从 PDF 到图像等... ):
import { saveAs } from 'file-saver';
// ...
saveGenericFile(api: string, fileinfos: any, idFile: string): any {
let mediaType = 'application/pdf';
let fileName = '';
if (fileinfos != null) {
mediaType = fileinfos.contentType;
fileName = fileinfos.fileName;
}
const headers = this.base.commonHeader;
const url = this.baseUrl + api + '?id=' + idFile;
this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
(response) => {
// tslint:disable-next-line: prefer-const
let blob = new Blob([response], { type: mediaType });
saveAs(blob, fileName);
}, e => {
console.error(e);
this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
}, () => {
/* do nothing */
}
);
}
正如我上面所说,这段代码 sn-p 工作正常,但只是当我必须从网络版本中保存一些东西时。
我能找到的唯一在线示例都是关于 Cordova 和/或以前/已弃用的版本。
关于电容器,我刚刚找到了this documentation,并从中找到了这段代码sn-p:
import { Plugins, FilesystemDirectory, FilesystemEncoding } from '@capacitor/core';
const { Filesystem } = Plugins;
fileWrite() {
try {
Filesystem.writeFile({
path: 'secrets/text.txt',
data: "This is a test",
directory: FilesystemDirectory.Documents,
encoding: FilesystemEncoding.UTF8
});
} catch(e) {
console.error('Unable to write file', e);
}
}
但问题是我上面的函数返回一个 blob,而这个函数只接受一个字符串作为数据。
那么,是否有任何 Capacitor-Native 等效功能可用于在作为 Web 应用程序和 Android 本机应用程序运行时下载(和保存)Blob 文件?
更新
我也尝试了以下方法,但它不起作用:
saveGenericFile(api: string, fileinfos: any, gidFile: string): any {
let mediaType = 'application/pdf';
let fileName = '';
if (fileinfos != null) {
mediaType = fileinfos.contentType;
fileName = fileinfos.fileName;
}
const headers = this.base.commonHeader;
const url = this.baseUrl + api + '?id=' + gidFile;
this.http.post(url, null, { headers, responseType: 'blob' }).subscribe(
(response) => {
if (!this.useCordovaDl) {
// tslint:disable-next-line: prefer-const
let blob = new Blob([response], { type: mediaType });
saveAs(blob, fileName);
} else {
this.blobFileWrite(fileName, response);
}
}, e => {
console.error(e);
this.toastsvc.generateToast('ERROR! An error occurred while saving this File, try later or contact support', 'danger');
}, () => {
/* do nothing */
}
);
}
blobFileWrite(filename: string, blobfile: Blob) {
const reader = new FileReader();
// This fires after the blob has been read/loaded.
reader.addEventListener('loadend', (e: any) => {
const text = e.srcElement.result;
this.fileWrite(filename, text);
});
// Start reading the blob as text.
reader.readAsText(blobfile);
}
fileWrite(filename: string, filedata: string) {
try {
Filesystem.writeFile({
path: filename,
data: filedata
// ,
// directory: FilesystemDirectory.Documents,
// encoding: FilesystemEncoding.UTF8
});
} catch (e) {
console.error('Unable to write file', e);
}
}
更新 #2
看起来像there's still an opened issue on GitHub 关于使用 Capacitor 保存 Blob 数据。同时,我将寻找 Cordova 解决方案。或者,如果平台是 android 或 ios,我将简单地禁用每个下载按钮。
如果我能找到一个,我会在此处发布所有可用的 Cordova 解决方法
【问题讨论】:
-
使用 FileReader 可以工作,除非您安装了 cordova-plugin-file 并使用 angular,因为 angular 的 zonejs 会导致阻止 FileReader 工作的错误
-
@jcesarmobile 您好,感谢您的评论!实际上,我将 Ionic 4 与 Angular 7 一起使用,所以这可以解释为什么 FileReader 不起作用。有没有关于这个的github问题?
-
是的github.com/ionic-team/capacitor/issues/1564,见最后一条评论,它有一个解决方法的链接
-
只是想插话说电容器社区 HTTP 插件会下载文件:github.com/capacitor-community/http
-
嗨@ingage,感谢您的评论!不知道那个repo,我一定会试一试
标签: typescript ionic-framework ionic4 capacitor