Angolare – file caricato POST

Sto usando Angular , TypeScript per inviare un file, insieme a JSON Data a un server.

Di seguito è riportato il mio codice:

import {Component, View, NgFor, FORM_DIRECTIVES, FormBuilder, ControlGroup} from 'angular2/angular2'; import {Http, Response, Headers} from 'http/http'; @Component({ selector: 'file-upload' }) @View({ directives: [FORM_DIRECTIVES], template: ` 

File Upload

Select file:
` }) export class FileUploadCmp { public file: File; public url: string; headers: Headers; constructor(public http: Http) { console.log('file upload Initialized'); //set the header as multipart this.headers = new Headers(); this.headers.set('Content-Type', 'multipart/form-data'); this.url = 'http://localhost:8080/test'; } //onChange file listener changeListener($event): void { this.postFile($event.target); } //send post file to server postFile(inputValue: any): void { var formData = new FormData(); formData.append("name", "Name"); formData.append("file", inputValue.files[0]); this.http.post(this.url +, formData , { headers: this.headers }); } }

Come posso trasformare formData in String e inviarlo al server? Ricordo in AngularJS (v1) che useresti transformRequest .

Guarda il mio codice, ma attenzione. Uso async / await, perché l’ultima versione beta di Chrome è in grado di leggere qualsiasi codice es6, che viene ottenuto da TypeScript con la compilazione. Quindi, devi sostituire asyns / await di .then() .

Input change handler:

 /** * @param fileInput */ public psdTemplateSelectionHandler (fileInput: any){ let FileList: FileList = fileInput.target.files; for (let i = 0, length = FileList.length; i < length; i++) { this.psdTemplates.push(FileList.item(i)); } this.progressBarVisibility = true; } 

Invia gestore:

 public async psdTemplateUploadHandler (): Promise { let result: any; if (!this.psdTemplates.length) { return; } this.isSubmitted = true; this.fileUploadService.getObserver() .subscribe(progress => { this.uploadProgress = progress; }); try { result = await this.fileUploadService.upload(this.uploadRoute, this.psdTemplates); } catch (error) { document.write(error) } if (!result['images']) { return; } this.saveUploadedTemplatesData(result['images']); this.redirectService.redirect(this.redirectRoute); } 

FileUploadService. Quel servizio memorizzava anche il caricamento in corso di progresso in $ proprietà, e in altri luoghi, è ansible iscriversi su di esso e ottenere un nuovo valore ogni 500ms.

 import { Component } from 'angular2/core'; import { Injectable } from 'angular2/core'; import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/share'; @Injectable() export class FileUploadService { /** * @param Observable */ private progress$: Observable; /** * @type {number} */ private progress: number = 0; private progressObserver: any; constructor () { this.progress$ = new Observable(observer => { this.progressObserver = observer }); } /** * @returns {Observable} */ public getObserver (): Observable { return this.progress$; } /** * Upload files through XMLHttpRequest * * @param url * @param files * @returns {Promise} */ public upload (url: string, files: File[]): Promise { return new Promise((resolve, reject) => { let formData: FormData = new FormData(), xhr: XMLHttpRequest = new XMLHttpRequest(); for (let i = 0; i < files.length; i++) { formData.append("uploads[]", files[i], files[i].name); } xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.response)); } else { reject(xhr.response); } } }; FileUploadService.setUploadUpdateInterval(500); xhr.upload.onprogress = (event) => { this.progress = Math.round(event.loaded / event.total * 100); this.progressObserver.next(this.progress); }; xhr.open('POST', url, true); xhr.send(formData); }); } /** * Set interval for frequency with which Observable inside Promise will share data with subscribers. * * @param interval */ private static setUploadUpdateInterval (interval: number): void { setInterval(() => {}, interval); } } 

Esaminando questo problema Github – Richiesta / Carica la gestione dell’avanzamento via @ angular / http , angular2 http non supporta ancora il caricamento di file.

Per il caricamento di file di base ho creato tale funzione di servizio come soluzione alternativa (utilizzando la risposta di Тимофей ):

  uploadFile(file:File):Promise { return new Promise((resolve, reject) => { let xhr:XMLHttpRequest = new XMLHttpRequest(); xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.response)); } else { reject(xhr.response); } } }; xhr.open('POST', this.getServiceUrl(), true); let formData = new FormData(); formData.append("file", file, file.name); xhr.send(formData); }); } 

il tuo file di servizio http:

 import { Injectable } from "@angular/core"; import { ActivatedRoute, Router } from '@angular/router'; import { Http, Headers, Response, Request, RequestMethod, URLSearchParams, RequestOptions } from "@angular/http"; import {Observable} from 'rxjs/Rx'; import { Constants } from './constants'; declare var $: any; @Injectable() export class HttpClient { requestUrl: string; responseData: any; handleError: any; constructor(private router: Router, private http: Http, private constants: Constants, ) { this.http = http; } postWithFile (url: string, postData: any, files: File[]) { let headers = new Headers(); let formData:FormData = new FormData(); formData.append('files', files[0], files[0].name); // For multiple files // for (let i = 0; i < files.length; i++) { // formData.append(`files[]`, files[i], files[i].name); // } if(postData !=="" && postData !== undefined && postData !==null){ for (var property in postData) { if (postData.hasOwnProperty(property)) { formData.append(property, postData[property]); } } } var returnReponse = new Promise((resolve, reject) => { this.http.post(this.constants.root_dir + url, formData, { headers: headers }).subscribe( res => { this.responseData = res.json(); resolve(this.responseData); }, error => { this.router.navigate(['/login']); reject(error); } ); }); return returnReponse; } } 

chiama la tua funzione (file componente):

 onChange(event) { let file = event.srcElement.files; let postData = {field1:"field1", field2:"field2"}; // Put your form data variable. This is only example. this._service.postWithFile(this.baseUrl + "add-update",postData,file).then(result => { console.log(result); }); } 

il tuo codice html:

  

Nel mio progetto, utilizzo XMLHttpRequest per inviare multipart / form-data. Penso che ti starà bene.

e il codice del caricatore

 let xhr = new XMLHttpRequest(); xhr.open('POST', 'http://www.example.com/rest/api', true); xhr.withCredentials = true; xhr.send(formData); 

Ecco un esempio: https://github.com/wangzilong/angular2-multipartForm

Innanzitutto, devi creare la tua TS-Class in linea, poiché la class FormData non è ben supportata al momento:

 var data : { name: string; file: File; } = { name: "Name", file: inputValue.files[0] }; 

Quindi lo invii al server con JSON.stringify (dati)

 let opts: RequestOptions = new RequestOptions(); opts.method = RequestMethods.Post; opts.headers = headers; this.http.post(url,JSON.stringify(data),opts);