使用 HttpClient 上传图片 [英] Upload image with HttpClient
问题描述
问题
我尝试使用 angular 的 HttpClient
上传图片API Content-Type: multipart/form-data
(angular v4+).是否支持?怎么做?
使用 XMLHttpRequest
>ng2-fancy-image-uploader.我更喜欢使用带有 HttpClient
的自定义方法,我可以将它与其他访问 API 的方法一起放入 http 服务中.
这是我迄今为止尝试过的:
model.service.ts
import { Injectable } from '@angular/core';从@angular/common/http"导入 { HttpClient, HttpHeaders, HttpResponse };导入 'rxjs/add/operator/toPromise';@Injectable()导出类 ModelService {构造函数(私有http:HttpClient){}public async updateAvatar(file: File): Promise{//标题const 标头 = 新的 HttpHeaders().append('Content-Type', 'multipart/form-data');const formData: FormData = new FormData();formData.append('avatar', file, file.name);const 响应:HttpResponse = 等待 this.http.patch('https://example.com/avatar', formData, { 标题,观察:'响应' }).承诺();控制台日志(响应状态);}}
avatar-uploader.component.ts
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';从 './path/to/model.service' 导入 { ModelService };@零件({选择器:'app-avatar-uploader',模板:'<input type="file" #fileInput (changes)="uploadAvatar()">'})导出类 AvatarUploaderComponent 实现 OnInit {@ViewChild('fileInput') fileInputElement: ElementRef;构造函数(){}ngOnInit() { }公共异步上传头像(){const 文件:文件 = this.fileInputElement.nativeElement.files[0];等待 this.model.updateAvatar(file);}}
这个版本向(express)API发送请求,但是multer
(解析multipart/form-data
请求的库)解析请求失败.>
所以我想我要么错误地使用了 HttpClient
,要么它不支持 multipart/form-data
请求.
我想可以发送 base64 编码的文件或使用 XmlHttpRequest
,但我特别询问 HttpClient
的能力.
对我来说,诀窍是不要将 content-type 设置为 multipart/form-data.但这对我来说是自动完成的.
这是我上传 multipart/form-data 的代码.无需设置标题.
private setFile(event) {让文件 = event.srcElement.files如果(!文件){返回}让路径 = `${environment.celoApiEndpoint}/api/patientFiles`让数据 = {患者数据":{"uid": "",名": "",姓": "","性别": "未指定",出生日期": ""}}//让 headers = new HttpHeaders()//.set('content-type', 'multipart/form-data;boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW')//let headers = new HttpHeaders().set('content-type', 'multipart/form-data')const formData: FormData = new FormData();for (let i = 0; i {console.log('得到 r', r)})}
Problem
I try to upload an image with angular's HttpClient
to API Content-Type: multipart/form-data
(angular v4+). Is it supported? How to do it?
The upload works with XMLHttpRequest
when using module like ng2-fancy-image-uploader
. I would prefer to use a custom method with HttpClient
which i could put into a http service together with other methods for accessing API.
Here is what i have tried so far:
model.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpResponse } from '@angular/common/http';
import 'rxjs/add/operator/toPromise';
@Injectable()
export class ModelService {
constructor(private http: HttpClient) { }
public async updateAvatar(file: File): Promise<void> {
// headers
const headers = new HttpHeaders()
.append('Content-Type', 'multipart/form-data');
const formData: FormData = new FormData();
formData.append('avatar', file, file.name);
const response: HttpResponse = await this.http
.patch('https://example.com/avatar', formData, { headers, observe: 'response' })
.toPromise();
console.log(response.status);
}
}
avatar-uploader.component.ts
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { ModelService } from './path/to/model.service';
@Component({
selector: 'app-avatar-uploader',
template: '<input type="file" #fileInput (changes)="uploadAvatar()">'
})
export class AvatarUploaderComponent implements OnInit {
@ViewChild('fileInput') fileInputElement: ElementRef;
constructor() { }
ngOnInit() { }
public async uploadAvatar() {
const file: File = this.fileInputElement.nativeElement.files[0];
await this.model.updateAvatar(file);
}
}
This version sends a request to (express) API, but multer
(a library for parsing multipart/form-data
requests) fails to parse the request.
So i guess i either use the HttpClient
incorrectly, or it doesn't support multipart/form-data
requests.
I guess one could send base64 encoded file or use XmlHttpRequest
, but i ask specifically about HttpClient
's ability to do it.
For me the trick was not to set the content-type to multipart/form-data. But that was done automatically for me.
<label>
<input type="file" (change)="setFiles($event)" style="display:none" multiple/>
<a mat-raised-button color="primary">
<mat-icon>file_upload</mat-icon>
Select Documents
</a>
</label>
Here's my code that uploads multipart/form-data. No need to set the headers.
private setFile(event) {
let files = event.srcElement.files
if (!files) {
return
}
let path = `${environment.celoApiEndpoint}/api/patientFiles`
let data = {"patientData": {
"uid": "",
"firstName": "",
"lastName": "",
"gender": "Not Specified",
"dateOfBirth": ""
}}
// let headers = new HttpHeaders()
// .set('content-type', 'multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW')
// let headers = new HttpHeaders().set('content-type', 'multipart/form-data')
const formData: FormData = new FormData();
for (let i = 0; i < files.length; i++) {
formData.append(i.toString(), files[i], files[i].name);
}
formData.append("data", JSON.stringify(data));
this.http.post(path, formData).subscribe(
(r)=>{console.log('got r', r)}
)
}
这篇关于使用 HttpClient 上传图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!