我想使用 FormData 将图像上传到后端,但由于 Ionic DEVAPP 和 Ionic VIEW 不支持文件、文件传输和文件上传插件,我需要仅使用 Angular Http 或 HttpClient 来完成此操作。
使用 DestinationType.FILE_URI 时,我可以从文件中获取内部 url 并将其显示在 img 对象上,但如果没有本机文件、文件路径和文件传输插件,我无法从此 url 创建打字稿文件对象。
getImage() {
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY
}
this.camera.getPicture(options).then((imageData) => {
this.imageURI = this.sanitizer.bypassSecurityTrustUrl(imageData)
}, (err) => {
console.log(err)
this.presentToast(err)
})
}
使用此模板
<ion-content padding>
<ion-item>
<p>{{imageFileName}}</p>
<button ion-button color="secondary" (click)="getImage()">Get Image</button>
</ion-item>
<ion-item>
<h4>Image Preview</h4>
<img style="display:block" [src]="imageURI" *ngIf="imageURI" alt="Ionic File" width="300" />
</ion-item>
<ion-item>
<button ion-button (click)="uploadFile()">Upload</button>
</ion-item>
</ion-content>
使用 DestinationType.DATA_URL 时,我可以显示图像,但无法创建原始文件名所需的打字稿文件对象,以将图像附加到我的 Ionic 应用程序的上传服务中使用的 FormData。
看来我可以找到一种方法来使用来自cordova相机本机插件的camera.getPicture,使用来自FILE_URI的原始文件名和来自DATA_URL的base64编码数据来创建这个打字稿文件对象。
将文件上传到我的后端的服务仅使用这种方法:
postImage(image: File): Observable<any> {
const formData = new FormData()
.append('file', image, image.name)
}
return this.httpClient.post<any>(this.myUrl,formData)
}
组件 myPage.ts 中的 getImage 和 uploadservice.ts 中的 postImage 都工作正常,但我找不到从camera.getPicture imageData 创建 File 对象的方法
Ionic 只是低效、无价值且无用的堆栈之上的另一层复杂性。在这种情况下,JS -> TS -> Angular -> (cordova - 电容器) -> Ionic。 如果您在某些问题上需要帮助,您会发现每一层都在指责其他层。 如果您需要一个依赖较少的多平台移动开发工具,最好使用其他不基于 JS 的工具。
如果你不想使用原生插件,你可以随时使用 Angular。对于这种情况,请使用离子输入文件:
<ion-input type="file"></ion-input>
剩下的用 Angular 来做: https://www.academind.com/learn/angular/snippets/angular-image-upload-made-easy/
您可以使用这个例子:
https://github.com/diegogplfree/Ionic3-fileupload-non-native
亲切的问候。
答案主要取自here,但适用于
@ionic-native/camera
插件getPicture
命令。
private urltoFile(url, filename, mimeType) {
return (fetch(url)
.then(function(res){return res.arrayBuffer();})
.then(function(buf){return new File([buf], filename, {type:mimeType});})
);
}
getPicture() {
const options: CameraOptions = {
quality: 50,
destinationType: this.camera.DestinationType.DATA_URL,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
correctOrientation: true
}
this.camera.getPicture(options).then((imageData) => {
let base64Image = 'data:image/jpeg;base64,' + imageData
this.urltoFile(base64Image, 'filename.jpg', 'image/jpeg')
.then((file) => {
// You now have a file object that you can attach to a form e.g.
this.myForm.get("imageToUpload").setValue(file)
})
}, (err) => {
// Handle error
});
}
需要注意的要点是
DATA_URL
data:image/jpeg;base64,
前面加上
imageData
我也遇到了同样的问题,并且喜欢这个,它对我有用。但需要注意的一件事是我不会首先显示所选图像。上传后仅可见。
openImage() {
const options: CameraOptions = {
quality: 100,
destinationType: this.camera.DestinationType.FILE_URI,
sourceType: this.camera.PictureSourceType.PHOTOLIBRARY,
correctOrientation: true,
allowEdit: false
};
this.camera.getPicture(options).then(imageData => {
this.ImageFile = imageData;
}, err => {
this.commonProvider.showToast('Error occured while opening the image' + err);
});
}
upload(msg: string) {
this.businessProvider.upload(this.Id, this.ImageFile)
.then(
data => {
let response = JSON.parse(data["response"]);
if (response.code === '1') {
this.commonProvider.showToast('Business successfully ' + msg);
this.navCtrl.pop();
} else {
this.commonProvider.showToast(response.message);
}
this.commonProvider.dismissLoader();
},
error => {
this.commonProvider.showToast(JSON.stringify(error));
this.commonProvider.dismissLoader();
}
);
}
这是我的业务提供商
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { ErrorObservable } from 'rxjs/observable/ErrorObservable';
import { catchError } from 'rxjs/operators';
import { Constant } from '../app/app.constants';
import { AuthenticationProvider } from '../providers/authentication';
import { FileTransfer, FileUploadOptions, FileTransferObject } from '@ionic-native/file-transfer';
@Injectable()
export class BusinessProvider {
private actionUrl: string;
constructor(
private http: HttpClient,
private auth: AuthenticationProvider,
private constant: Constant,
private transfer: FileTransfer
) {
this.actionUrl = this.constant.getServerWithApiUrl() + 'Business/';
}
upload(Id: number, ImageFile): any {
const fileTransfer: FileTransferObject = this.transfer.create();
const headers = this.auth.getHeader();
let options: FileUploadOptions = {
fileKey: 'ionicfile',
fileName: 'ionicfile.jpg',
chunkedMode: false,
mimeType: "image/jpeg",
headers: { headers }
}
return fileTransfer.upload(ImageFile, this.actionUrl + 'Upload/' + Id, options);
}
}