Angular4 后台管理系統搭建(10) - 做一個通用的可跨域上傳文件的組件


    寫的很慢,不知不覺這是第十篇了。但是我其他事情太多,只能抽空寫下。現在angular4或angular2流行的上傳方式是ng2-file-upload。它的功能很強大。但是我沒有配置成可以跨域上傳的。好像是不支持跨域上傳,不知道對錯。jquery的插件 jQuery File Upload 可以跨域上傳。但是想在angular4內使用jquery插件。需要找到全局jquery對象。也是很麻煩。所以這里就自己實現一個可跨域上傳的功能。

    demo整體設計有三個站點,第一個是純前台的,提供對html,js,各種資源的web訪問支持就可以。可以用iis,apache,nginx 來支撐。第二個是純后台的用來提供restful接口服務,這里用tomcat。第三個是資源站點。提供對用戶上傳的種種文件的訪問,可以用iis,apache,nginx 。這里三個站點詳細的url是:

     ①前台   http://121.42.203.123       

  ②后台   http://121.42.203.123:8080     

     ③資源站點  http://121.42.203.123:83

    圖片上傳的流程是在前台站點上傳文件,傳遞給后台站點的接口。后台站點把文件寫到資源站點上。框架內圖片上傳是可以和表單上傳混合在一起的。就是在一個post或put內,同時傳遞上傳文件和表單數據。但是這樣,上傳功能就是和具體業務關聯在一起。我們需要的通用性就丟失了。所以我的思路是父類組件內有一個文本框后面接一個按鈕。點擊按鈕彈出子組件一個小窗口。在小窗口內上傳文件。然后把遠程的文件路徑返回給父組件,傳遞到文本框內。做了兩個例子。一個是添加或修改用戶信息時。選取用戶頭像圖片的。

       

    還有一個是專門用來展示上傳操作demo的

    

   

    上傳文件組件html代碼如下,比較簡陋,也沒有預覽功能。以后在擴展吧。

<template #templateUploadFile>
  <div class="modal-header" style="background:#EAEAEA;">
    <h5 class="modal-title pull-left">
      <b>文件上傳</b>
    </h5>
    <button type="button" class="close pull-right" aria-label="Close" (click)="closeModal()">
      <span aria-hidden="true">×</span>
    </button>
  </div>
  <div class="modal-body">
    <form #form="ngForm" enctype="multipart/form-data" novalidate>
      <input type="file" id="sef" name="sef" class="form-control" ngModel (change)="onSelectChange($event)">
      <div *ngIf="this.isError==true" style="color:red">{{this.stringError}}</div>
    </form>
  </div>
</template>

  對應后台代碼如下

 1 import { Component, OnInit, Input, Inject, ViewChild, TemplateRef, ElementRef, Output, EventEmitter } from '@angular/core';
 2 import { BsModalService } from 'ngx-bootstrap/modal';
 3 import { BsModalRef } from 'ngx-bootstrap/modal/modal-options.class';
 4 
 5 import { FileUploader, FileUploaderOptions } from 'ng2-file-upload';
 6 import ConstantsList from '../../common/constants/config';
 7 import { BackCode } from '../../module/common/common';
 8 import { UserNews } from '../../module/business/login';
 9 
10 @Component({
11   selector: 'app-uploadfile',
12   templateUrl: './uploadfile.component.html',
13   styleUrls: ['./uploadfile.component.css']
14 })
15 export class UploadfileComponent implements OnInit {
16 
17   @ViewChild('templateUploadFile') public template: TemplateRef<any>;
18   modalRef: BsModalRef;
19   ModalConfig = { animated: false, keyboard: false, backdrop: true, ignoreBackdropClick: true, };
20   @Input() public userNews: UserNews;
21   @Output() weburl: EventEmitter<string> = new EventEmitter<string>();
22   isError:boolean = false;
23   stringError:string;
24 
25   constructor(private modalService: BsModalService, @Inject('public_service') private publicservice: any) { }
26 
27   ngOnInit() { }
28 
29   openModal(template: TemplateRef<any>) {
30     this.modalRef = this.modalService.show(template, Object.assign({}, this.ModalConfig, { class: 'modal-sm' }));
31   }
32 
33   closeModal() {
34     this.modalRef.hide();
35     this.modalRef = null;
36     this.stringError = '';
37     this.isError = false;
38   }
39 
40   public show() {
41     this.openModal(this.template);
42     this.stringError = '';
43     this.isError = false;
44   }
45 
46   onSelectChange(event: EventTarget) {
47     let eventObj: MSInputMethodContext = <MSInputMethodContext>event;
48     let target: HTMLInputElement = <HTMLInputElement>eventObj.target;
49     let files: FileList = target.files;
50     let file: File = files[0];
51     
52     if(this.checkIsImage(file.name) == true) {
53       this.isError = false;
54       this.stringError = '';
55       let postData = null;
56       let sendtoken: string = this.userNews.id + '-' + this.userNews.token + '-' + ConstantsList.runid;
57 
58       this.publicservice.postWithFile1(sendtoken, postData, files).then(ub => {
59         let bc: BackCode = ub as BackCode;
60         this.weburl.emit(ConstantsList.HOSTPIC + bc.id);
61       });
62     } 
63     else{
64       this.isError = true;
65       this.stringError = '請確定文件格式為 jpg png jpeg bmp gif';
66     }
67   }
68 
69   checkIsImage(filename: string): boolean {
70     let filenameend:string = '|' + filename.slice(filename.lastIndexOf('.') + 1) + '|';
71     if ('|jpg|png|jpeg|bmp|gif|'.indexOf(filenameend.toLowerCase()) !== -1) {
72       return true;
73     } else {
74       return false;
75     }
76   }
77 
78 }
View Code

    服務端ssm框架內,接收post的地方關鍵就是要添加下面幾個信息。

  response.setHeader("Access-Control-Allow-Origin", "*");
  response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,OPTIONS,DELETE");
  response.setHeader("Access-Control-Max-Age", "3600");
  response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type,Access-Token");

 其他的接收文件。寫文件網上都很多例子。這里用自定義的http頭信息進行校驗。防止其他路徑上非法的post上傳文件。但是不是絕對的。這里展示一下這個功能。

    demo演示地址是  http://121.42.203.123

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM