subir mostrar insertar img imagenes imagen angular http typescript file-upload multipartform-data

mostrar - subir imagen angular 4



Subir imagen con HttpClient (2)

Problema

Intento subir una imagen con HttpClient a API Content-Type: multipart/form-data angular Content-Type: multipart/form-data (angular v4 +). ¿Es compatible? ¿Cómo hacerlo?

La carga funciona con XMLHttpRequest cuando se usa un módulo como ng2-fancy-image-uploader . Preferiría usar un método personalizado con HttpClient que podría poner en un servicio http junto con otros métodos para acceder a la API.

Esto es lo que he intentado hasta ahora:

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); } }

Esta versión envía una solicitud a (expreso) API, pero multer (una biblioteca para analizar solicitudes multipart/form-data ) no puede analizar la solicitud.

Así que supongo que o bien uso incorrectamente el HttpClient , o no es compatible multipart/form-data solicitudes de multipart/form-data .

Supongo que uno podría enviar un archivo codificado en base64 o utilizar XmlHttpRequest , pero le pregunto específicamente sobre la capacidad de HttpClient para hacerlo.


No creo que el problema sea angular, utilicé el mismo código para enviar un archivo al servidor (estoy usando Spring en el backend), la única diferencia es que no estoy observando la solicitud o convirtiendo la respuesta en una promesa.

ver mi código a continuación

let formData: FormData = new FormData(); formData.append(''file'', this.fileToUpload); this.http.put(this.usersUrl , formData) .subscribe( data => { console.log(data); }, error => { console.log(error); } );


Para mí, el truco no era establecer el tipo de contenido en multipart / form-data. Pero eso se hizo automáticamente por mí.

<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>

Aquí está mi código que carga multipart / form-data. No es necesario configurar los encabezados.

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)} ) }