Загрузка Файлов В Angular?
Я знаю, что это очень общий вопрос, но я не могу загрузить файл в Angular 2. Я пробовал
1) http://valor-software.com/ng2-file-upload/ и
2) http://ng2-uploader.com/home
...но не получилось. Кто-нибудь загрузил файл в угловой? Какой метод вы использовали? Как это сделать? Если какой-либо пример кода или демо-ссылка предоставляется, это будет действительно оценено.
12 ответов:
Угловое 2 обеспечивает хорошую поддержку для загрузки файла. Любая сторонняя библиотека не требуется.
<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) ) } }
используя @angular / core": "~2.0.0 " и @angular / http:"~2.0.0"
из ответов выше я строю это с угловой 5.x
просто позвони
uploadFile(url, file).subscribe()
для запуска загрузки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); } }
используйте его так в вашем компоненте
// 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"); } ) }
спасибо @Eswar. Этот код отлично работал для меня. Я хочу добавить некоторые вещи в решение:
Я получаю ошибку :
java.io.IOException: RESTEASY007550: Unable to get boundary for multipart
чтобы устранить эту ошибку, вы должны удалить "Content-Type" "multipart/form-data". Это решило мою проблему.
поскольку пример кода немного устарел, я подумал, что поделюсь более поздним подходом, используя Angular 4.3 и новый (er) HttpClient API, @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 }
в угловой 2+, это очень важно оставить Content-Type пустой. Если вы установите "Content-Type" в "multipart/form-data", загрузка не будет работать !
загрузить.деталь.HTML-код
<input type="file" (change)="fileChange($event)" name="file" />
загрузить.деталь.ТС
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) ); } } }
Я использовал следующий инструмент от грунтовки с успехом. У меня нет кожи в игре с primeNg, просто передавая мое предложение.
Это простое решение сработало для меня: file-upload.деталь.HTML-код
<div> <input type="file" #fileInput placeholder="Upload file..." /> <button type="button" (click)="upload()">Upload</button> </div>
а затем сделать загрузку в компоненте непосредственно с 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); } } }
если вы используете ядро dotnet, имя параметра должно совпадать с именем поля from. файлы в этом случае:
[HttpPost("[action]")] public async Task<IList<FileDto>> UploadFiles(List<IFormFile> files) { return await _binaryService.UploadFilesAsync(files); }
этот ответ является плагиатом http://blog.teamtreehouse.com/uploading-files-ajax
Edit: После загрузки вы должны очистить файл-загрузить, чтобы пользователь мог выбрать новый файл. И вместо использования XMLHttpRequest, может быть, лучше использовать 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); }); }
это полезный учебник, как загрузить файл с помощью ng2-file-upload и без ng2-file-upload.
для меня это очень помогает.
на данный момент учебник содержит несколько ошибок:
1-клиент должен иметь тот же url-адрес загрузки, что и сервер, так что в
app.component.ts
изменить строку
const URL = 'http://localhost:8000/api/upload';
до
const URL = 'http://localhost:3000';
2-сервер отправляет ответ как "текст / html", так и в
app.component.ts
изменить.post(URL, formData).map((res:Response) => res.json()).subscribe( //map the success function and alert the response (success) => { alert(success._body); }, (error) => alert(error))
до
.post(URL, formData) .subscribe((success) => alert('success'), (error) => alert(error));
чтобы загрузить изображение с полями формы
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); }
В моем случае мне нужен .NET Web Api в 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); }
Я загрузил файл с помощью ссылки. Пакет не требуется для загрузки файла.
/ / код для записи .файл 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, }); }); }
}
// код, который будет написан в сервисе.файл 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);
}
// код должен быть написан в HTML
<input type="file" #fileInput>
попробуйте не устанавливать
options
параметр
this.http.post(${this.apiEndPoint}, formData)
и убедитесь, что вы не задание
globalHeaders
в вашем Http-заводе.
сегодня я был интегрирован ng2-file-upload пакет для моего углового приложения 6, это было довольно просто, Пожалуйста, найдите ниже код высокого уровня.
импорт ng2-file-upload модуль
приложение.модуль.ТС
import { FileUploadModule } from 'ng2-file-upload'; ------ ------ imports: [ FileUploadModule ], ------ ------
компонент ts file import FileUploader
приложение.деталь.ТС
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); } ------ ------
компонент HTML добавить файл тег
приложение.деталь.HTML-код
<input type="file" #fileInput ng2FileSelect [uploader]="uploader" (onFileSelected)="onFileSelected($event)" />
работая онлайн ссылка stackblitz:https://ng2-file-upload-example.stackblitz.io
Stackblitz пример кода:https://stackblitz.com/edit/ng2-file-upload-example
ссылка на официальную документацию https://valor-software.com/ng2-file-upload/