Angular – Fichier téléchargé POST

J’utilise Angular , TypeScript pour envoyer un fichier, avec des données JSON vers un serveur.

Voici mon code:

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

Comment transformer le formData en Ssortingng et l’envoyer au serveur? Je me souviens que dans AngularJS (v1), vous utiliseriez transformRequest .

Regardez mon code, mais soyez conscient. J’utilise async / waiting, car la dernière version bêta de Chrome peut lire n’importe quel code es6, qui est fourni par TypeScript avec la compilation. Vous devez donc remplacer asyns / .then() par .then() .

Gestionnaire de changement d’entrée:

 /** * @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; } 

Soumettre le gestionnaire:

 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. Ce service stocke également la progression du téléchargement dans la propriété progress $ et, à d’autres endroits, vous pouvez vous y abonner et obtenir une nouvelle valeur toutes les 500 ms.

 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: ssortingng, 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); } } 

En regardant ce problème, Github – Gestion des requêtes / téléchargements via @ angular / http , angular2 http ne supporte pas encore le téléchargement de fichiers.

Pour le téléchargement de fichiers très basique, j’ai créé cette fonction de service en guise de solution de contournement (en utilisant la réponse de Тимофей ):

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

votre fichier de service 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: ssortingng; responseData: any; handleError: any; constructor(private router: Router, private http: Http, private constants: Constants, ) { this.http = http; } postWithFile (url: ssortingng, 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; } } 

appelez votre fonction (fichier de composants):

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

votre code html:

  

Dans mon projet, j’utilise le XMLHttpRequest pour envoyer des données multipart / form-data. Je pense que cela vous conviendra.

et le code uploader

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

Voici l’exemple: https://github.com/wangzilong/angular2-multipartForm

Tout d’abord, vous devez créer votre propre classe TS en ligne, car la classe FormData n’est pas bien prise en charge pour le moment:

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

Ensuite, vous l’envoyez au serveur avec JSON.ssortingngify (data)

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