【问题标题】:Build multipart/form-data POST request in Angular2 and validate Input type File在 Angular2 中构建 multipart/form-data POST 请求并验证输入类型文件
【发布时间】:2016-04-27 21:12:44
【问题描述】:

我有一个图像 (base64),需要通过 POST 请求发送(并等待响应)。 POST 请求必须是Content-Type:multipart/form-data。 图片必须是Content-Type: image/jpg

POST 请求应如下所示:

POST https://www.url... HTTP/1.1
Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
User-Agent: Fiddler
Host: www.host.com
Content-Length: 199640

---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="Nikon Digital SLR Camera D3100 14.2MP 2.jpg"
Content-Type: image/jpeg

以二值图像数据为内容体。

我正在尝试使用 Angular 2 的 Http Post 方法,但我不太确定如何生成请求。 这就是我所拥有的:

let body = atob(imageData);
let headers = new Headers({'Content-Type': 'multipart/form-data'});
let options = new RequestOptions({headers: headers});

this._http.post(url, body, options)
.map(res=>{
  //do stuff
});

我可以说我遗漏了其中的一部分,但我不确定我需要做什么才能将二进制图像数据提供为 Content-Disposition & Type 等。

【问题讨论】:

    标签: javascript angular typescript post angular2-forms


    【解决方案1】:

    Form template

    <form id="form" name="file" [formGroup]="FileFormGroup"(submit)="addFrom($event, FileFormGroup)" method="post">  
    
       <input spellcheck="true" formControlName="Demo" name="Demo" type="text"/>
       <input type="file" accept="image/*" id="file" name="File"/>
       <input formControlName="File" type="hidden"/>
    
    </form>
    

    Ts

       import {FormGroup, FormBuilder, FormControl, Validators} from '@angular/forms';
    
       import {ValidatorFn} from '@angular/forms/src/directives/validators';
    
       public FileFormGroup: FormGroup; /* variable */
    
       constructor(public fb: FormBuilder) {}
    
       ngOnInit() {
          this.FileFormGroup = this.fb.group({
          Demo: ["", Validators.required],
          File: ["", this.fileExtension({msg: 'Please upload valid Image'})]
         });
       }
    
       public addFrom(event: Event, form: FormGroup): void {
    
       if(form.valid && form.dirty) {
    
       let formTemp: HTMLFormElement <HTMLFormElement>document.querySelector('#form');
    
       let formData: FormData = new FormData(formTemp);
    
       let xhr: XMLHttpRequest = this.foo(formData);
    
        xhr.onreadystatechange = () => {
          if(xhr.readyState === 4) {
            if(xhr.status === 201) {
               console.log("Success");
            } else {
               console.log("Error");
            }
          }
        }
      }}
    
        // Foo function
         public Foo(formData){
             let url: Foo;
             let xhr: XMLHttpRequest = new XMLHttpRequest();
             xhr.open('POST', url, true);
    
             // enctype For Multipart Request
              xhr.setRequestHeader("enctype", "multipart/form-data");
    
              // IE bug fixes to clear cache
              xhr.setRequestHeader("Cache-Control", "no-cache");
              xhr.setRequestHeader("Cache-Control", "no-store");
              xhr.setRequestHeader("Pragma", "no-cache"); 
    
              xhr.send(formData);
              return xhr;
         }
    
         /* validation function to check proper file extension */
    
      public fileExtension(config: any): ValidatorFn {
        return (control: FormControl) => {
    
          let urlRegEx: RegExp = /\.(jpe?g|png|gif)$/i;
    
          if(control.value && !control.value.match(urlRegEx)) {
            this.deleteImg = false;
            return {
              invalidUrl: config.msg
            };
          } else {
            return null;
          }
        };
      }
    

    【讨论】:

      【解决方案2】:

      此处与此问题类似:Angular 2 - Post File to Web API

      Angular2 尚不支持 multipart/form-data POST 请求,所以我决定改用 jQuery 来实现它,然后将其转换为 RxJs Observable(主题)以与 http.post 函数具有相同的类型在 Angular2 中应该有:

      //Convert Base64 Representation of jpeg to 
      let imageData = imageString.split(',')[1];
      let dataType = imageString.split('.')[0].split(';')[0].split(':')[1];
      let binaryImageData = atob(imageData);
      let data = new FormData();
      let blob = new Blob([binaryImageData], { type: dataType })
      data.append('file', blob);
      let deferred = $.ajax({
        url: this._imageAPIBaseUrl,
        data: data,
        cache: false,
        contentType: false,
        processData: false,
        type: 'POST'
      });
      let observable = new AsyncSubject();
      
      //When the Deferred is complete, push an item through the Observable
      deferred.done(function () {
      
        //Get the arguments as an array
        let args = Array.prototype.slice.call(arguments);
      
        //Call the observable next with the same parameters
        observable.next.apply(observable, args);
      
        //Complete the Observable to indicate that there are no more items.
        observable.complete();
      });
      
      //If the Deferred errors, push an error through the Observable
      deferred.fail(function () {
      
        //Get the arguments as an array
        let args = Array.prototype.slice.call(arguments);
      
        //Call the observable error with the args array
        observable.error.apply(observable, args);
        observable.complete();
      });
      
      return observable;
      

      【讨论】:

        【解决方案3】:

        请检查这个工作示例(不是我的):https://plnkr.co/edit/ViTp47ecIN9kiBw23VfL?p=preview

        1 - 不要更改或设置 Content-Type

        2 - 使用FormData发送参数

        3 - 将此添加到 app.module.ts:

        import { HttpModule, RequestOptions, XHRBackend, ConnectionBackend, Http, Request, RequestOptionsArgs, Response, Headers } from '@angular/http';
        @Injectable()
        export class HttpInterceptor extends Http {
            constructor(backend: ConnectionBackend, defaultOptions: RequestOptions) 
            {
                super(backend, defaultOptions);
                defaultOptions.headers = new Headers();
                defaultOptions.headers.append('Content-Type', 'application/json');
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-08-08
          • 2018-11-19
          • 1970-01-01
          相关资源
          最近更新 更多