page navigationend cambiar angular file-upload angular2-http

navigationend - title angular 6



Subir archivo en angular? (13)

Sé que esta es una pregunta muy general, pero no puedo cargar un archivo en Angular 2. He intentado

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

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

...pero falló. ¿Alguien ha subido un archivo en Angular? ¿Qué método usaste? ¿Cómo hacerlo? Si se proporciona algún código de muestra o enlace de demostración, será realmente apreciado.


Angular 2 proporciona un buen soporte para cargar archivos. No se requiere una biblioteca de terceros.

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

utilizando @ angular / core ":" ~ 2.0.0 "y @ angular / http:" ~ 2.0.0 "


Como el código de muestra está un poco desactualizado, pensé en compartir un enfoque más reciente, usando Angular 4.3 y la nueva (er) 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 }


En Angular 2+, es muy importante dejar vacío el Tipo de contenido . Si configura ''Content-Type'' en ''multipart / form-data'', la carga no funcionará.

upload.component.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) ); } } }


En la forma más simple, el siguiente código funciona en Angular 6/7

this.http.post("http://destinationurl.com/endpoint", fileFormData) .subscribe(response => { //handle response }, err => { //handle error });

Aquí está la implementación completa


Esta solución simple funcionó para mí: file-upload.component.html

<div> <input type="file" #fileInput placeholder="Upload file..." /> <button type="button" (click)="upload()">Upload</button> </div>

Y luego realice la carga en el componente directamente con XMLHttpRequest .

import { Component, OnInit, ViewChild } from ''@angular/core''; @Component({ selector: ''app-file-upload'', templateUrl: ''./file-upload.component.html'', styleUrls: [''./file-upload.component.css''] }) export class FileUploadComponent implements OnInit { @ViewChild(''fileInput'') fileInput; constructor() { } ngOnInit() { } private upload() { const fileBrowser = this.fileInput.nativeElement; if (fileBrowser.files && fileBrowser.files[0]) { const formData = new FormData(); formData.append(''files'', fileBrowser.files[0]); const xhr = new XMLHttpRequest(); xhr.open(''POST'', ''/api/Data/UploadFiles'', true); xhr.onload = function () { if (this[''status''] === 200) { const responseText = this[''responseText'']; const files = JSON.parse(responseText); //todo: emit event } else { //todo: error handling } }; xhr.send(formData); } } }

Si está utilizando dotnet core, el nombre del parámetro debe coincidir con el nombre del campo from. archivos en este caso:

[HttpPost("[action]")] public async Task<IList<FileDto>> UploadFiles(List<IFormFile> files) { return await _binaryService.UploadFilesAsync(files); }

Esta respuesta es un plagio de http://blog.teamtreehouse.com/uploading-files-ajax

Editar : después de cargar, debe borrar la carga del archivo para que el usuario pueda seleccionar un nuevo archivo. Y en lugar de usar XMLHttpRequest, tal vez sea mejor usar fetch:

private addFileInput() { const fileInputParentNative = this.fileInputParent.nativeElement; const oldFileInput = fileInputParentNative.querySelector(''input''); const newFileInput = document.createElement(''input''); newFileInput.type = ''file''; newFileInput.multiple = true; newFileInput.name = ''fileInput''; const uploadfiles = this.uploadFiles.bind(this); newFileInput.onchange = uploadfiles; oldFileInput.parentNode.replaceChild(newFileInput, oldFileInput); } private uploadFiles() { this.onUploadStarted.emit(); const fileInputParentNative = this.fileInputParent.nativeElement; const fileInput = fileInputParentNative.querySelector(''input''); if (fileInput.files && fileInput.files.length > 0) { const formData = new FormData(); for (let i = 0; i < fileInput.files.length; i++) { formData.append(''files'', fileInput.files[i]); } const onUploaded = this.onUploaded; const onError = this.onError; const addFileInput = this.addFileInput.bind(this); fetch(''/api/Data/UploadFiles'', { credentials: ''include'', method: ''POST'', body: formData, }).then((response: any) => { if (response.status !== 200) { const error = `An error occured. Status: ${response.status}`; throw new Error(error); } return response.json(); }).then(files => { onUploaded.emit(files); addFileInput(); }).catch((error) => { onError.emit(error); }); }

https://github.com/yonexbat/cran/blob/master/cranangularclient/src/app/file-upload/file-upload.component.ts


Gracias a @Eswar. Este código funcionó perfectamente para mí. Quiero agregar ciertas cosas a la solución:

java.io.IOException: RESTEASY007550: Unable to get boundary for multipart error: java.io.IOException: RESTEASY007550: Unable to get boundary for multipart

Para resolver este error, debe eliminar el "Contenido-Tipo" "multipart / form-data". Solucionó mi problema.


He subido el archivo con referencia. No se requiere ningún paquete para cargar el archivo de esta manera.

// código que se escribirá en el archivo .ts

@ViewChild("fileInput") fileInput; addFile(): void { let fi = this.fileInput.nativeElement; if (fi.files && fi.files[0]) { let fileToUpload = fi.files[0]; this.admin.addQuestionApi(fileToUpload) .subscribe( success => { this.loading = false; this.flashMessagesService.show(''Uploaded successfully'', { classes: [''alert'', ''alert-success''], timeout: 1000, }); }, error => { this.loading = false; if(error.statusCode==401) this.router.navigate(['''']); else this.flashMessagesService.show(error.message, { classes: [''alert'', ''alert-danger''], timeout: 1000, }); }); }

}

// código que se escribirá en el archivo service.ts

addQuestionApi(fileToUpload: any){ var headers = this.getHeadersForMultipart(); let input = new FormData(); input.append("file", fileToUpload); return this.http.post(this.baseUrl+''addQuestions'', input, {headers:headers}) .map(response => response.json()) .catch(this.errorHandler);

}

// código que se escribirá en html

<input type="file" #fileInput>



Hoy estaba integrado el ng2-file-upload en mi aplicación angular 6, fue bastante simple, encuentra el siguiente código de alto nivel.

importar el módulo ng2-file-upload

app.module.ts

import { FileUploadModule } from ''ng2-file-upload''; ------ ------ imports: [ FileUploadModule ], ------ ------

Componente ts importación de archivos FileUploader

app.component.ts

import { FileUploader, FileLikeObject } from ''ng2-file-upload''; ------ ------ const URL = ''http://localhost:3000/fileupload/''; ------ ------ public uploader: FileUploader = new FileUploader({ url: URL, disableMultipart : false, autoUpload: true, method: ''post'', itemAlias: ''attachment'' }); public onFileSelected(event: EventEmitter<File[]>) { const file: File = event[0]; console.log(file); } ------ ------

Componente HTML agregar etiqueta de archivo

app.component.html

<input type="file" #fileInput ng2FileSelect [uploader]="uploader" (onFileSelected)="onFileSelected($event)" />

Trabajando en línea stackblitz Link: https://ng2-file-upload-example.stackblitz.io

Ejemplo de código de Stackblitz: https://stackblitz.com/edit/ng2-file-upload-example

Enlace de documentación oficial https://valor-software.com/ng2-file-upload/


Intente no configurar el parámetro de options

this.http.post(${this.apiEndPoint}, formData)

y asegúrese de no configurar globalHeaders en su fábrica Http.


Este es un tutorial útil sobre cómo cargar archivos usando ng2-file-upload y SIN ng2-file-upload.

Para mí me ayuda mucho.

Por el momento, el tutorial contiene un par de errores:

1- El cliente debe tener la misma URL de carga que un servidor, por lo que en app.component.ts cambia la línea

const URL = ''http://localhost:8000/api/upload'';

a

const URL = ''http://localhost:3000'';

2- El servidor envía la respuesta como ''text / html'', por lo que en app.component.ts cambia

.post(URL, formData).map((res:Response) => res.json()).subscribe( //map the success function and alert the response (success) => { alert(success._body); }, (error) => alert(error))

a

.post(URL, formData) .subscribe((success) => alert(''success''), (error) => alert(error));


A partir de las respuestas anteriores, construyo esto con Angular 5.x

Simplemente llame a uploadFile(url, file).subscribe() para activar una carga

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

Úselo así en su componente

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


Para cargar una imagen con campos de formulario

SaveFileWithData(article: ArticleModel,picture:File): Observable<ArticleModel> { let headers = new Headers(); // headers.append(''Content-Type'', ''multipart/form-data''); // headers.append(''Accept'', ''application/json''); let requestoptions = new RequestOptions({ method: RequestMethod.Post, headers:headers }); let formData: FormData = new FormData(); if (picture != null || picture != undefined) { formData.append(''files'', picture, picture.name); } formData.append("article",JSON.stringify(article)); return this.http.post("url",formData,requestoptions) .map((response: Response) => response.json() as ArticleModel); }

En mi caso, necesitaba .NET Web Api en C #

// POST: api/Articles [ResponseType(typeof(Article))] public async Task<IHttpActionResult> PostArticle() { Article article = null; try { HttpPostedFile postedFile = null; var httpRequest = HttpContext.Current.Request; if (httpRequest.Files.Count == 1) { postedFile = httpRequest.Files[0]; var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName); postedFile.SaveAs(filePath); } var json = httpRequest.Form["article"]; article = JsonConvert.DeserializeObject <Article>(json); if (!ModelState.IsValid) { return BadRequest(ModelState); } article.CreatedDate = DateTime.Now; article.CreatedBy = "Abbas"; db.articles.Add(article); await db.SaveChangesAsync(); } catch (Exception ex) { int a = 0; } return CreatedAtRoute("DefaultApi", new { id = article.Id }, article); }