1) http://valor-software.com/ng2-file-upload/和
2) http://ng2-uploader.com/home
...但失败了。有人在Angular中上传过文件吗?你用了什么方法?怎么做呢?如果提供了任何示例代码或演示链接,将非常感谢。
我已经成功地使用了下面的工具。我和primeNg没有利害关系,只是传递我的建议。
http://www.primefaces.org/primeng/#/fileupload
Angular 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"
感谢@Eswar。这段代码非常适合我。我想在解决方案中添加一些东西:
我得到错误:java.io.IOException: RESTEASY007550: Unable to get boundary for multipart
java.io.IOException: RESTEASY007550: Unable to get boundary for multipart
为了解决这个错误,你应该删除“Content-Type”“multipart/form-data”。它解决了我的问题。
这个教程很有用,如何使用ng2-file-upload和不使用ng2-file-upload上传文件。
对我来说很有帮助。
目前,教程包含几个错误:
1-客户端应该有相同的上传url作为服务器, 所以在app.component.ts更改line
app.component.ts
const URL = 'http://localhost:8000/api/upload';
来
const URL = 'http://localhost:3000';
2-服务器发送响应为'text/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));
这个简单的解决方案适用于我:file-upload.component.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 core,参数名必须与from字段名匹配。本例中的文件:
[HttpPost("[action]")] public async Task<IList<FileDto>> UploadFiles(List<IFormFile> files) { return await _binaryService.UploadFilesAsync(files); }
这个答案抄袭了http://blog.teamtreehouse.com/uploading-files-ajax
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
由于代码示例有点过时,我想我应该分享一个更近期的方法,使用Angular 4.3和新的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 }
在Angular 2+中,让内容类型为空非常符合重要的。如果您将“内容类型”设置为“multipart/form-data”,则上传将无法工作!
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) ); } } }
我已经上传文件使用引用。以这种方式上传文件不需要包。
//要写入.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>
根据上面的答案,我用Angular 5.x构建了这个
只需调用uploadFile(url, file).subscribe()来触发上传
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"); } ) }
上传带有表单字段的图像
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); }
尽量不要设置options参数
options
this.http.post(${this.apiEndPoint}, formData)
并确保你没有在Http工厂中设置globalHeaders。
globalHeaders
今天我集成了ng2-file-upload包到我的angular 6应用程序,这是相当简单的,请找到下面的高级代码。
导入ng2-file-upload模块
app.module.ts
import { FileUploadModule } from 'ng2-file-upload'; ------ ------ imports: [ FileUploadModule ], ------ ------
组件的文件导入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添加文件标签
app.component.html
<input type="file" #fileInput ng2FileSelect [uploader]="uploader" (onFileSelected)="onFileSelected($event)" />
Working Online stackblitz链接: https://ng2-file-upload-example.stackblitz.io
Stackblitz代码示例: https://stackblitz.com/edit/ng2-file-upload-example
官方文档链接https://valor-software.com/ng2-file-upload/
下面的代码以最简单的形式在Angular 6/7中工作
this.http.post("http://destinationurl.com/endpoint", fileFormData) .subscribe(response => { //handle response }, err => { //handle error });
这里是完整实现
jspdf和Angular 8
我生成了一个pdf,并希望通过POST请求上传pdf,这就是我所做的(为了清晰起见,我删除了一些代码和服务层)
import * as jsPDF from 'jspdf'; import { HttpClient } from '@angular/common/http'; constructor(private http: HttpClient) upload() { const pdf = new jsPDF() const blob = pdf.output('blob') const formData = new FormData() formData.append('file', blob) this.http.post('http://your-hostname/api/upload', formData).subscribe() }