angular2^ typescript 將 文件和Json數據 合並發送到服務器(1.客戶端處理)
首先介紹下框架基本流程 (web > webservice 【前端架構】 ) > (nodejs 【 數據中轉站 】) >(api 【後臺接口】)
--web (html angular 框架)
--webservice(angular 中 編寫的service文件 ,在此處原本可以使用 【ng2-file-upload】插件 文件+參數 合並提交,但是在我的項目中 請求需要統一提交,所以在此處 使用第三方插件不太適用
所以自己編寫了XMLHttpRequest 進行 form data 合並提交, angular http post 是不可以的,所以使用了 XMLHttpRequest)
--nodejs (nodejs 做 webserver,從瀏覽器上傳文件到後端服務器,nodejs 層只是做一個數據中轉+參數加密 == ,nodejs 需)
--api ( 這個就簡單介紹一下, php java .net nodejs == 都是可以得 只是統一好請求參數和 出入參數就ok)
》》》》本次參考文章有以下(可能angular2 目前國內使用不是特別熟練,在國內搜索答案找不到,只好硬著頭皮FQ看英文【英語不好只能用翻譯軟件了 :( 】)
github stack overflow
https://github.com/asafdav/ng-csv
https://stackoverflow.com/questions/37174759/how-do-you-post-a-formdata-object-in-angular-2
https://stackoverflow.com/questions/36352405/file-upload-with-angular2-to-rest-api
https://stackoverflow.com/questions/32423348/angular-post-uploaded-file
本篇文章 主要介紹 前端 (web > webservice 【前端架構】 ) 數據合並提交,下篇文章主要介紹 後端 數據合並提交
1. component
-----1. html 編寫
<input type="file" (change)="filechange($event)"/>
-----2. ts
import { Component, OnInit } from [email protected]/core‘; import { Router } from "@angular/router"; //引入 公共 service提交 import { ApiService, EditAlbumParam } from "app/service/api.service"; @Component({ selector: ‘app-albumEdit‘, templateUrl: ‘./albumEdit.component.html‘, styleUrls: [‘./albumEdit.component.css‘] }) export class AlbumEditComponent implements OnInit { private albumTypeData; private file: File[]; private editAlbumParam: EditAlbumParam = new EditAlbumParam(); constructor( private api: ApiService, private router: Router) { } ngOnInit() { } //主要實現方法 當文件修改時 接受一下 filechange(event) { this.file = event.srcElement.files; } //提交事件 submit() { //將參數和文件統一提交 this.api.editAlbum(this.editAlbumParam, this.file).subscribe(res => { if (res.State == 0) { alert("添加成功!"); } }); } }
2. api.service.ts (所有component 進行 api 請求的必進之路)
import { Injectable } from [email protected]/core‘; import { Http, Headers, RequestOptions } from "@angular/http"; import { Observable } from "rxjs/Rx"; import "rxjs/Rx"; import { UploadService } from "app/service/upload.service"; @Injectable() export class ApiService { constructor(private http: Http, private upload: UploadService) { } private post(data: ParamData): Observable<ResponseInfo> { let host = "/serverH5"; let bodyObj = { cmd: data.cmd, param: JSON.stringify(data.param) }; let body = `cmd=${data.cmd}¶m=${JSON.stringify(data.param)}`; console.log("send infomation : " + body); //當發現文件流時 進行 form data 合並提交 調用公用upload service if (data.file) { return this.upload.makeFileRequest(host, bodyObj, data.file).map(res => res as ResponseInfo) .filter((res: ResponseInfo) => { console.log(res); if (res.State == 1) { alert(res.Msg); } return res.State == 0; }); } else { let myHeaders = new Headers(); myHeaders.append(‘Content-Type‘, ‘application/x-www-form-urlencoded‘); return this.http.post( host, body, { headers: myHeaders } ) .map(res => res.json() as ResponseInfo) .filter((res: ResponseInfo) => { console.log(res); if (res.State == 1) { alert(res.Msg); } return res.State == 0; }); } } //登錄 login(param: LoginParam) { return this.post(new ParamData("LoginBySms", param)); } //發送驗證碼 sendCode(param: LoginParam) { return this.post(new ParamData("SmsULogin", param)); } //獲取專輯類型 getAlbumType() { return this.post(new ParamData("AlbumType", {})); } //獲取專輯列表 getAlbumList(param: AlbumListParam) { return this.post(new ParamData("MyAlbumList", param)); } //添加修改專輯 editAlbum(param: EditAlbumParam, file?: File[]) { return this.post(new ParamData("UserAddAlbum", param, file)); } } export class ParamData { /** * */ constructor( public cmd: string, public param: object, public file?: File[] ) { } } export class ResponseInfo { /** * */ constructor( public State?: number, public Msg?: string, public Value?: any ) { } } export class LoginParam { public Phone?: number; public Code?: number; } export class AlbumListParam { public PageIndex: number; public PageSize: number; public Guid: string; public CType?: string; } export class EditAlbumParam { public Name: string; public Guid: string; public Introduce: string; public Id: number; public Price: string; public CTypeId: string; public RId: number; public RType: number; }
3. upload service.ts 編寫
import { Injectable } from [email protected]/core‘; import { Observable } from ‘rxjs/Rx‘; import ‘rxjs/add/operator/share‘; @Injectable() export class UploadService { [x: string]: any; constructor() { this.progress$ = Observable.create(observer => { this.progressObserver = observer }).share(); } public makeFileRequest(url: string, postData: any, files: File[]): Observable<Response> { return Observable.create(observer => { let formData: FormData = new FormData(), xhr: XMLHttpRequest = new XMLHttpRequest(); //formData 文件流追加 for (let i = 0; i < files.length; i++) { formData.append("uploads[]", files[i], files[i].name); } //formData 參數追加 if (postData !== "" && postData !== undefined && postData !== null) { for (var property in postData) { if (postData.hasOwnProperty(property)) { formData.append(property, postData[property]); } } } xhr.onreadystatechange = () => { if (xhr.readyState === 4) { if (xhr.status === 200) { observer.next(xhr.response); observer.complete(); } else { observer.error(xhr.response); } } }; 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); }); } }
下篇文章主要介紹 後端 數據合並提交
如有寫的不對的地方,請指出,並建議,謝謝 :)
angular2^ typescript 將 文件和Json數據 合並發送到服務器(1.客戶端處理)