web-dev-qa-db-ja.com

multipart / form-data POSTリクエストをAngular2でビルドし、入力タイプファイルを検証します

POSTリクエストを介して送信する必要がある(そして応答を待つ)画像(base64)があります。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のHttpPostメソッドを使用しようとしていますが、リクエストを生成する方法がよくわかりません。これが私が持っているものです。

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
});

その一部が欠落していることはわかりますが、バイナリイメージデータにコンテンツ(配置とタイプなど)を与えるために何をする必要があるのか​​わかりません。

7
Gabe O'Leary

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;
      }
    };
  }
4
mayur

この作業例を確認してください(私のものではありません): 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');
    }
}
0
Alessandro

ここでのこの質問に似ています: Angular 2-Web APIへのファイルの投稿

Angular2はまだmultipart/form-data POSTリクエストをサポートしていないので、代わりにjQueryを使用して実装し、RxJs Observable(サブジェクト)に変換して同じタイプにすることにしました。 Angular2のhttp.post関数に必要なもの:

//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;
0
Gabe O'Leary