Angular - POST 上传的文件 [英] Angular - POST uploaded file
问题描述
我正在使用 Angular、TypeScript 将文件和 JSON 数据一起发送到服务器.
下面是我的代码:
import {Component, View, NgFor, FORM_DIRECTIVES, FormBuilder, ControlGroup} from 'angular2/angular2';从http/http"导入 {Http, Response, Headers};@Component({ 选择器: '文件上传' })@看法({指令:[FORM_DIRECIVES],模板:`<h3>文件上传</h3><div>选择文件:<input type="file" (change)="changeListener($event)">
`})导出类 FileUploadCmp {公共文件:文件;公共网址:字符串;标题:标题;构造函数(公共http:Http){console.log('文件上传初始化');//将标题设置为多部分this.headers = new Headers();this.headers.set('Content-Type', 'multipart/form-data');this.url = 'http://localhost:8080/test';}//onChange文件监听器changeListener($event): void {this.postFile($event.target);}//发送post文件到服务器后文件(输入值:任何):无效{var formData = new FormData();formData.append("name", "Name");formData.append("file", inputValue.files[0]);this.http.post(this.url +,表单数据,{标头:this.headers});}}
如何将 formData
转换为 String 并将其发送到服务器?我记得在 AngularJS (v1) 中你会使用 transformRequest
.
看我的代码,但要注意.我使用 async/await,因为最新的 Chrome beta 可以读取任何 es6 代码,这些代码由 TypeScript 编译获得.所以,你必须用 .then()
替换 asyns/await.
输入更改处理程序:
/*** @param 文件输入*/公共 psdTemplateSelectionHandler (fileInput: any){让 FileList: FileList = fileInput.target.files;for (let i = 0, length = FileList.length; i < length; i++) {this.psdTemplates.push(FileList.item(i));}this.progressBarVisibility = true;}
提交处理程序:
public async psdTemplateUploadHandler(): Promise{让结果:任何;如果(!this.psdTemplates.length){返回;}this.isSubmitted = true;this.fileUploadService.getObserver().订阅(进度=> {this.uploadProgress = 进度;});尝试 {结果 = 等待 this.fileUploadService.upload(this.uploadRoute, this.psdTemplates);} 捕捉(错误){文档写(错误)}如果(!结果['图像']){返回;}this.saveUploadedTemplatesData(result['images']);this.redirectService.redirect(this.redirectRoute);}
文件上传服务.该服务还将上传进度存储在 progress$ 属性中,在其他地方,您可以订阅它并每 500 毫秒获取一次新值.
import { Component } from 'angular2/core';从'angular2/core'导入{可注射};从 'rxjs/Observable' 导入 { Observable };导入 'rxjs/add/operator/share';@Injectable()导出类 FileUploadService {/*** @param Observable<数字>*/私人进度$: Observable;/*** @type {数字}*/私人进度:数字 = 0;私人进度观察者:任何;构造函数(){this.progress$ = new Observable(observer => {this.progressObserver = 观察者});}/*** @returns {Observable}*/public getObserver(): Observable{返回 this.progress$;}/*** 通过 XMLHttpRequest 上传文件** @param url* @param 文件* @returns {Promise}*/公开上传(网址:字符串,文件:文件[]):承诺<任何>{返回新的承诺((解决,拒绝)=> {让 formData: FormData = new FormData(),xhr: XMLHttpRequest = new XMLHttpRequest();for (let i = 0; i {如果(xhr.readyState === 4){如果(xhr.status === 200){解析(JSON.parse(xhr.response));} 别的 {拒绝(xhr.response);}}};FileUploadService.setUploadUpdateInterval(500);xhr.upload.onprogress = (事件) =>{this.progress = Math.round(event.loaded/event.total * 100);this.progressObserver.next(this.progress);};xhr.open('POST', url, true);xhr.send(formData);});}/*** 设置 Promise 内部 Observable 与订阅者共享数据的频率间隔.** @param 间隔*/私有静态 setUploadUpdateInterval(间隔:数字):void {setInterval(() => {}, 间隔);}}
I'm using Angular, TypeScript to send a file, along with JSON Data to a server.
Below is my 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: `
<h3>File Upload</h3>
<div>
Select file:
<input type="file" (change)="changeListener($event)">
</div>
`
})
export class FileUploadCmp {
public file: File;
public url: string;
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
});
}
}
How can I transform the formData
to String and send it to the server? I remember in AngularJS (v1) you would use transformRequest
.
Look at my code, but be aware. I use async/await, because latest Chrome beta can read any es6 code, which gets by TypeScript with compilation. So, you must replace asyns/await by .then()
.
Input change handler:
/**
* @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;
}
Submit handler:
public async psdTemplateUploadHandler (): Promise<any> {
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. That service also stored uploading progress in progress$ property, and in other places, you can subscribe on it and get new value every 500ms.
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<number>
*/
private progress$: Observable<number>;
/**
* @type {number}
*/
private progress: number = 0;
private progressObserver: any;
constructor () {
this.progress$ = new Observable(observer => {
this.progressObserver = observer
});
}
/**
* @returns {Observable<number>}
*/
public getObserver (): Observable<number> {
return this.progress$;
}
/**
* Upload files through XMLHttpRequest
*
* @param url
* @param files
* @returns {Promise<T>}
*/
public upload (url: string, files: File[]): Promise<any> {
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);
}
}
这篇关于Angular - POST 上传的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!