如何强制 HTML 输入文件选择器在 Ionic(Android) 中给出原始文件名?
How to force HTML input file chooser to give the original file name in Ionic(Android)?
我正在使用 HTML input
在我的 Ionic3/Angular 应用程序中选择文件。我正在使用以下代码:
// 在 .html 文件中
<input #fileUpload type="file" name="myfile"(change)="onFileChoose($event)"/>
// 在 .ts 文件中
onFileChoose($event): void {
this.fileChooser.getFileInfo($event).then((result) => {
this.fileName = result.fileName;
this.fileData = this.sanitizeFileData(result.fileData);
this.fileSize = result.fileSize;
this.fileType = result.fileType;
}, (error) => {
this.helperProvider.createAlert('Alert', 'File is corrupted.');
});
}
getFileInfo(event: Event): Promise<any> {
let target = event && event.target;
let files: Array<File> = target && target['files'];
console.log(files[0].type);
console.log(files[0].name);
return new Promise((resolve, reject) => {
if (files && files.length) {
files = Array.from(files);
let fileName = files[0].name;
let fileSize = files[0].size;
let fileType = files[0].type;
let fileReader = new FileReader();
fileReader.onload = () => resolve({
fileData: fileReader.result,
fileName: fileName,
fileSize: fileSize,
fileType: fileType
});
fileReader.onerror = error => reject(error);
fileReader.onabort = error => reject(error);
fileReader.readAsDataURL(files[0])
}
});
}
这在 iOS
和 Browser
中运行良好。在 android 和浏览器中,我都可以获得文件的原始名称、大小和类型。但是问题出现在Android.
场景 1(Android): 当我使用文件选择器选择图像文件时,我可以得到原始文件名、大小和类型文件。
场景 2(Android): 当我选择图像文件以外的文件时 .pdf,.doc 等等,我无法得到原始文件名和文件类型。假设,我选择了一个文件名“sample.pdf”,但是在我选择文件之后,我得到的文件名是一个随机数,比如 45675 和 最重要的是文件类型,我得到的是空文件.
然后,我在 Whosebug 中进行了研究并看到了这些链接 (link1 and link2)。这可能是 android.
的安全问题
有一个 ionic-native/file-chooser 库,但它仅适用于 android 平台。
有什么办法强制android给原文件名吗?
Android 没有使用我的上述方法给出原始文件名和文件类型,这是 android 的安全问题。因此,我必须制定以下解决方案来检索正确的文件名、文件类型、文件大小和 base64 中的文件数据。
您将需要以下四个插件:
文件选择器Android提供者:
import {Injectable} from '@angular/core';
import {File, FileEntry, IFile} from "@ionic-native/file";
import {Base64} from "@ionic-native/base64";
import {FilePath} from "@ionic-native/file-path";
import {FileChooser} from "@ionic-native/file-chooser";
@Injectable()
export class FileChooserAndroidProvider {
constructor(private base64: Base64, private filePath: FilePath, private file: File, private fileChooser: FileChooser) {
}
getFileInfo(): Promise<any> {
return this.fileChooser.open().then((fileURI) => {
return this.filePath.resolveNativePath(fileURI).then((filePath) => {
return this.file.resolveLocalFilesystemUrl(filePath).then((fileEntry: FileEntry) => {
return new Promise((resolve, reject) => {
fileEntry.file(meta => resolve(meta), error => reject(error));
});
}).then((fileMeta: IFile) => {
return new Promise((resolve, reject) => {
return this.base64.encodeFile(filePath).then((base64Data) => {
resolve({
fileData: base64Data,
fileName: fileMeta.name,
fileSize: fileMeta.size,
fileType: fileMeta.type
})
}).catch((error) => {
reject(error);
})
})
});
});
});
}
}
FileChooserAndroidProviderModule:
import {NgModule} from '@angular/core';
import {Base64} from "@ionic-native/base64";
import {FileChooser} from "@ionic-native/file-chooser";
import {FilePath} from "@ionic-native/file-path";
import {File} from "@ionic-native/file";
@NgModule({
declarations: [],
exports: [],
providers: [
FileChooser,
File,
FilePath,
Base64
]
})
export class FileChooserAndroidProviderModule {
}
示例页面:
constructor(private fileChooserAndroid: FileChooserAndroidProvider){}
uploadFileForAndroid(): void {
this.fileChooserAndroid.getFileInfo().then((result) => {
this.fileName = result.fileName;
this.fileData = this.sanitizeFileData(result.fileData);
this.fileSize = result.fileSize;
this.fileType = result.fileType;
}).catch((error) => {
this.helperProvider.createAlert('Alert', 'File can not be uploaded.');
});
}
SamplePageModule:
@NgModule({
declarations: [
SamplePage
],
imports: [
FileChooserAndroidProviderModule
],
providers: [
FileChooserAndroidProvider
]
})
export class SamplePageModule {
}
我正在使用 HTML input
在我的 Ionic3/Angular 应用程序中选择文件。我正在使用以下代码:
// 在 .html 文件中
<input #fileUpload type="file" name="myfile"(change)="onFileChoose($event)"/>
// 在 .ts 文件中
onFileChoose($event): void {
this.fileChooser.getFileInfo($event).then((result) => {
this.fileName = result.fileName;
this.fileData = this.sanitizeFileData(result.fileData);
this.fileSize = result.fileSize;
this.fileType = result.fileType;
}, (error) => {
this.helperProvider.createAlert('Alert', 'File is corrupted.');
});
}
getFileInfo(event: Event): Promise<any> {
let target = event && event.target;
let files: Array<File> = target && target['files'];
console.log(files[0].type);
console.log(files[0].name);
return new Promise((resolve, reject) => {
if (files && files.length) {
files = Array.from(files);
let fileName = files[0].name;
let fileSize = files[0].size;
let fileType = files[0].type;
let fileReader = new FileReader();
fileReader.onload = () => resolve({
fileData: fileReader.result,
fileName: fileName,
fileSize: fileSize,
fileType: fileType
});
fileReader.onerror = error => reject(error);
fileReader.onabort = error => reject(error);
fileReader.readAsDataURL(files[0])
}
});
}
这在 iOS
和 Browser
中运行良好。在 android 和浏览器中,我都可以获得文件的原始名称、大小和类型。但是问题出现在Android.
场景 1(Android): 当我使用文件选择器选择图像文件时,我可以得到原始文件名、大小和类型文件。
场景 2(Android): 当我选择图像文件以外的文件时 .pdf,.doc 等等,我无法得到原始文件名和文件类型。假设,我选择了一个文件名“sample.pdf”,但是在我选择文件之后,我得到的文件名是一个随机数,比如 45675 和 最重要的是文件类型,我得到的是空文件.
然后,我在 Whosebug 中进行了研究并看到了这些链接 (link1 and link2)。这可能是 android.
的安全问题有一个 ionic-native/file-chooser 库,但它仅适用于 android 平台。
有什么办法强制android给原文件名吗?
Android 没有使用我的上述方法给出原始文件名和文件类型,这是 android 的安全问题。因此,我必须制定以下解决方案来检索正确的文件名、文件类型、文件大小和 base64 中的文件数据。
您将需要以下四个插件:
文件选择器Android提供者:
import {Injectable} from '@angular/core';
import {File, FileEntry, IFile} from "@ionic-native/file";
import {Base64} from "@ionic-native/base64";
import {FilePath} from "@ionic-native/file-path";
import {FileChooser} from "@ionic-native/file-chooser";
@Injectable()
export class FileChooserAndroidProvider {
constructor(private base64: Base64, private filePath: FilePath, private file: File, private fileChooser: FileChooser) {
}
getFileInfo(): Promise<any> {
return this.fileChooser.open().then((fileURI) => {
return this.filePath.resolveNativePath(fileURI).then((filePath) => {
return this.file.resolveLocalFilesystemUrl(filePath).then((fileEntry: FileEntry) => {
return new Promise((resolve, reject) => {
fileEntry.file(meta => resolve(meta), error => reject(error));
});
}).then((fileMeta: IFile) => {
return new Promise((resolve, reject) => {
return this.base64.encodeFile(filePath).then((base64Data) => {
resolve({
fileData: base64Data,
fileName: fileMeta.name,
fileSize: fileMeta.size,
fileType: fileMeta.type
})
}).catch((error) => {
reject(error);
})
})
});
});
});
}
}
FileChooserAndroidProviderModule:
import {NgModule} from '@angular/core';
import {Base64} from "@ionic-native/base64";
import {FileChooser} from "@ionic-native/file-chooser";
import {FilePath} from "@ionic-native/file-path";
import {File} from "@ionic-native/file";
@NgModule({
declarations: [],
exports: [],
providers: [
FileChooser,
File,
FilePath,
Base64
]
})
export class FileChooserAndroidProviderModule {
}
示例页面:
constructor(private fileChooserAndroid: FileChooserAndroidProvider){}
uploadFileForAndroid(): void {
this.fileChooserAndroid.getFileInfo().then((result) => {
this.fileName = result.fileName;
this.fileData = this.sanitizeFileData(result.fileData);
this.fileSize = result.fileSize;
this.fileType = result.fileType;
}).catch((error) => {
this.helperProvider.createAlert('Alert', 'File can not be uploaded.');
});
}
SamplePageModule:
@NgModule({
declarations: [
SamplePage
],
imports: [
FileChooserAndroidProviderModule
],
providers: [
FileChooserAndroidProvider
]
})
export class SamplePageModule {
}