202 votes

Téléchargement de fichiers en Angular ?

Je sais que c'est une question très générale mais je ne parviens pas à télécharger un fichier dans Angular 2. J'ai essayé

1) http://valor-software.com/ng2-file-upload/ et

2) http://ng2-uploader.com/home

...mais sans succès. Quelqu'un a-t-il téléchargé un fichier dans Angular ? Quelle méthode avez-vous utilisée ? Comment faire ? Si un exemple de code ou un lien de démonstration est fourni, ce sera vraiment apprécié.

417voto

Eswar Points 3737

Angular 2 offre un bon support pour le téléchargement de fichiers. Aucune bibliothèque tierce n'est requise.

<input type="file" (change)="fileChange($event)" placeholder="Upload file" accept=".pdf,.doc,.docx">

fileChange(event) {
    let fileList: FileList = event.target.files;
    if(fileList.length > 0) {
        let file: File = fileList[0];
        let formData:FormData = new FormData();
        formData.append('uploadFile', file, file.name);
        let headers = new Headers();
        /** In Angular 5, including the header Content-Type can invalidate your request */
        headers.append('Content-Type', 'multipart/form-data');
        headers.append('Accept', 'application/json');
        let options = new RequestOptions({ headers: headers });
        this.http.post(`${this.apiEndPoint}`, formData, options)
            .map(res => res.json())
            .catch(error => Observable.throw(error))
            .subscribe(
                data => console.log('success'),
                error => console.log(error)
            )
    }
}

en utilisant @angular/core" : "~2.0.0" et @angular/http : "~2.0.0".

1 votes

${this.apiEndPoint} montre l'erreur " unresolved variable" ! comment résoudre cela ? Où puis-je lire sur le téléchargement de fichiers dans angular2 ? quel site ? quel document fournit des informations détaillées ?

7 votes

Cela ne fonctionne pas, du moins dans mon cas. Le serveur sailsJs reçoit un tableau/objet de fichiers vide.

22 votes

Ça a marché pour moi, sauf que j'ai dû travailler sur cette ligne headers.append('enctype', 'multipart/form-data'); (utilisation de "enctype" pour remplacer "Content-Type"). Peut-être cela dépend-il du code côté serveur. (i.e. api)

87voto

Tarion Points 1867

D'après les réponses ci-dessus, je construis ceci avec Angular 5.x.

Appelez simplement uploadFile(url, file).subscribe() pour déclencher un téléchargement

import { Injectable } from '@angular/core';
import {HttpClient, HttpParams, HttpRequest, HttpEvent} from '@angular/common/http';
import {Observable} from "rxjs";

@Injectable()
export class UploadService {

  constructor(private http: HttpClient) { }

  // file from event.target.files[0]
  uploadFile(url: string, file: File): Observable<HttpEvent<any>> {

    let formData = new FormData();
    formData.append('upload', file);

    let params = new HttpParams();

    const options = {
      params: params,
      reportProgress: true,
    };

    const req = new HttpRequest('POST', url, formData, options);
    return this.http.request(req);
  }
}

Utilisez-le comme ceci dans votre composant

  // At the drag drop area
  // (drop)="onDropFile($event)"
  onDropFile(event: DragEvent) {
    event.preventDefault();
    this.uploadFile(event.dataTransfer.files);
  }

  // At the drag drop area
  // (dragover)="onDragOverFile($event)"
  onDragOverFile(event) {
    event.stopPropagation();
    event.preventDefault();
  }

  // At the file input element
  // (change)="selectFile($event)"
  selectFile(event) {
    this.uploadFile(event.target.files);
  }

  uploadFile(files: FileList) {
    if (files.length == 0) {
      console.log("No file selected!");
      return

    }
    let file: File = files[0];

    this.upload.uploadFile(this.appCfg.baseUrl + "/api/flash/upload", file)
      .subscribe(
        event => {
          if (event.type == HttpEventType.UploadProgress) {
            const percentDone = Math.round(100 * event.loaded / event.total);
            console.log(`File is ${percentDone}% loaded.`);
          } else if (event instanceof HttpResponse) {
            console.log('File is completely loaded!');
          }
        },
        (err) => {
          console.log("Upload Error:", err);
        }, () => {
          console.log("Upload done");
        }
      )
  }

6 votes

Fonctionne bien avec Angular6. Merci. Et vous avez besoin de ces bibliothèques à importer. import {HttpClient, HttpParams, HttpRequest, HttpEvent, HttpEventType, HttpResponse} from '@angular/common/http' ;

1 votes

Dans mon cas, j'utilisais un porteur d'autorisation et j'ai ajouté ce code supplémentaire let params = new HttpParams(); let headers = new HttpHeaders({ 'Authorization': 'Bearer ' + localStorage.getItem('accessToken'), }); const options = { headers: headers, params: params, reportProgress: true, };

0 votes

Il est intéressant de noter que les importations de Observable et HttpEvent pourrait être entièrement omis si vous êtes d'accord pour utiliser l'inférence de type pour fournir le type de retour de la fonction pour uploadFile() ! this.http.request() renvoie déjà un type de Observable<HttpEvent<{}>> Ainsi, si vous donnez à l'appel de la requête un type générique (c'est-à-dire this.http.request<any>() puis toute la fonction fonctionne avec les bons types.

25voto

heman123 Points 1339

Merci à @Eswar. Ce code a parfaitement fonctionné pour moi. Je veux ajouter certaines choses à la solution :

Je recevais l'erreur : java.io.IOException: RESTEASY007550: Unable to get boundary for multipart

Pour résoudre cette erreur, vous devez supprimer le "Content-Type" "multipart/form-data". Cela a résolu mon problème.

8 votes

+1. Si vous supprimez Content-Type, il est généré correctement. Par exemple : multipart/form-data; boundary=---------------------------186035562730765173675680‌​113 . Voir aussi stackoverflow.com/a/29697774/1475331 et github.com/angular/angular/issues/11819 .

1 votes

J'obtiens cette erreur java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found" qui est similaire à la vôtre, mais lorsque je retire l'option Content-Type Je reçois un 404 du backend à la place. Nous utilisons Spring et Angular 2. Toute aide est la bienvenue.

0 votes

Cela devrait être juste un commentaire sur sa réponse, n'est-ce pas ?

20voto

javahaxxor Points 54

Comme l'exemple de code est un peu dépassé, j'ai pensé partager une approche plus récente, en utilisant Angular 4.3 et la nouvelle API HttpClient, @angular/common/http.

export class FileUpload {

@ViewChild('selectedFile') selectedFileEl;

uploadFile() {
let params = new HttpParams();

let formData = new FormData();
formData.append('upload', this.selectedFileEl.nativeElement.files[0])

const options = {
    headers: new HttpHeaders().set('Authorization', this.loopBackAuth.accessTokenId),
    params: params,
    reportProgress: true,
    withCredentials: true,
}

this.http.post('http://localhost:3000/api/FileUploads/fileupload', formData, options)
.subscribe(
    data => {
        console.log("Subscribe data", data);
    },
    (err: HttpErrorResponse) => {
        console.log(err.message, JSON.parse(err.error).error.message);
    }
)
.add(() => this.uploadBtn.nativeElement.disabled = false);//teardown
}

1 votes

Avez-vous le code html pour cela ? J'aime le fait qu'il utilise HttpParams. Je me demandais juste si vous aviez un exemple fonctionnel complet quelque part. Merci

0 votes

De cette façon, comment puis-je télécharger plusieurs fichiers ensemble sous forme de tableau ? Comment doit-il être ajouté à l'objet de données du formulaire ?

0 votes

Examiner les données de formulaires multipartites webdavsystem.com/javaserver/doc/resumable_upload/multipart_post

19voto

abahet Points 2631

Dans Angular 2+, il est très important pour quitter le Content-Type vide. Si vous définissez le 'Content-Type' à 'multipart/form-data', le téléchargement ne fonctionnera pas !

télécharger.composant.html

<input type="file" (change)="fileChange($event)" name="file" />

upload.component.ts

export class UploadComponent implements OnInit {
    constructor(public http: Http) {}

    fileChange(event): void {
        const fileList: FileList = event.target.files;
        if (fileList.length > 0) {
            const file = fileList[0];

            const formData = new FormData();
            formData.append('file', file, file.name);

            const headers = new Headers();
            // It is very important to leave the Content-Type empty
            // do not use headers.append('Content-Type', 'multipart/form-data');
            headers.append('Authorization', 'Bearer ' + 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9....');
            const options = new RequestOptions({headers: headers});

            this.http.post('https://api.mysite.com/uploadfile', formData, options)
                 .map(res => res.json())
                 .catch(error => Observable.throw(error))
                 .subscribe(
                     data => console.log('success'),
                     error => console.log(error)
                 );
        }
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X