2016-05-11 13 views
26

muszę przesłać plik i wysłać jakąś json wraz z nim, mam tę funkcję:W jaki sposób POST obiekt FormData w Angular 2?

POST_formData(url, data) { 
     var headers = new Headers(), authtoken = localStorage.getItem('authtoken'); 

     if (authtoken) { 
      headers.append("Authorization", 'Token ' + authtoken) 
     } 

     headers.append("Accept", 'application/json'); 
     headers.delete("Content-Type"); 

     var requestoptions = new RequestOptions({ 
      method: RequestMethod.Post, 
      url: this.apiURL + url, 
      headers: headers, 
      body: data 
     }) 

     return this.http.request(new Request(requestoptions)) 

     .map((res: Response) => { 
      if (res) { 
       return { status: res.status, json: res.json() } 
      } 
     }) 
    } 

Mój problem jest, jeśli mogę ustawić content-type do „multipart/form-data” mój serwer narzeka granic, gdybym całkowicie usunąć nagłówek content-type, mój serwer narzeka, że ​​"text/plain" obsługiwany typ multimediów.

Jak wysłać formularz FormData z funkcją angle2?

+0

na FormData nie jest obecnie obsługiwane. Widzę komentarz todo '// TODO: support URLSearchParams | FormData | Blob | ArrayBuffer' in 'Request' class –

+0

Robienie tego, co masz teraz z kątowym 2, powinno zadziałać – acastano

+1

, aby zauważyć, że headers.delete (" Content-Type ") jest bardzo ważny dla przesyłania plików. Robiłem to: headers.set ("Content-Type", ""), ale to spowoduje kanciaste dodanie ciągu wieloczęściowego/danych formularza z przecinkiem (co spowoduje, że będzie on zniekształcony. dla tego rozwiązania, dzięki! –

Odpowiedz

9

To Open Isuue na Angular2 repozytorium Git, a istnieje również Pull Request czeka zostać połączone, mam nadzieję, że zostanie ona połączyła wkrótce.


Alternatywnie

Można użyć XMLHttpRequest obiektu bezpośrednio do tego.

I nie zapomnij, aby ustawić nagłówek

xhr.setRequestHeader("enctype", "multipart/form-data"); 

// IE workaround for Cache issues 
xhr.setRequestHeader("Cache-Control", "no-cache"); 
xhr.setRequestHeader("Cache-Control", "no-store"); 
xhr.setRequestHeader("Pragma", "no-cache"); 

na XMLHttpRequest że można zrobić.


Podobne pytania:

How to upload file in Angular2

Angular 2 File upload from input type=file

Angular2 post uploaded file

+2

Nie trzeba już używać XMLHttpRequest.To działa z http – acastano

+8

gist z przykładem https://gist.github.com/Toxicable/1c736ed16c95bcdc7612e2c406b5ce0f – surya

+0

Wielkie dzięki za link @surya, działało jak urok! – fxlemire

4

Znam ten został oznaczony odpowiedział i jest dość stary, jednak miałem problem delegowania Obiekt FormData do OpenIdConnect AuthServe r, a powyższe przykłady przesyłania plików nie były tym, czego szukałem.

Oto moja usługa, która dostaje OpenIdAuthToken:

import { Injectable } from '@angular/core'; 
import { Http, RequestOptions, Headers, URLSearchParams} from '@angular/http' 
import { OpenIdTokenRequest, SmartData } from '../model/openid-token-request'; 
import { OpenIdToken } from '../model/openid-token'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/Rx'; 
import { Observable } from 'rxjs'; 

@Injectable() 

export class TokenService { 

    constructor(private _http: Http) { } 

    getToken(requestData: OpenIdTokenRequest, smartData: SmartData) { 
     let _urlParams = new URLSearchParams(); 
     _urlParams.append('code', requestData.code); 
     _urlParams.append('grant_type', requestData.grantType); 
     _urlParams.append('redirect_uri', requestData.redirectUri); 
     _urlParams.append('client_id', requestData.clientId); 

     let _url = smartData.tokenUri; 
     let _options = this.getTokenPostOptions(); 

     return this._http.post(_url, _urlParams, _options) 
      .map(response => <OpenIdToken>response.json()) 
    } 

    private getTokenPostOptions(): RequestOptions { 

     let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }); 
     let options = new RequestOptions({ headers: headers }); 

     return options; 
    } 

} 
+0

Idealne dziękuję – rottenoats

15

Template:

<label class="btn btn-primary"> 
    <input type="file" style="display: none;" multiple="true" (change)="fileChange($event)" accept=".xml"> 
    <span>Click Me!</span> 
</label> 

UPD: kątowa 5 - HttpClient + Typescript

onFileUpload(event: EventTarget) { 

    const eventObj: MSInputMethodContext = <MSInputMethodContext>event; 
    const target: HTMLInputElement = <HTMLInputElement>eventObj.target; 
    const files: FileList = target.files; 

    const formData: FormData = new FormData(); 

    for (let i = 0; i < files.length; i++) { 
    formData.append('file', files[i]); 
    } 

    // POST 
    this.httpClient.post<AnalyzedData>(uploadUrl, formData).subscribe(...); 
} 

stare Http lib - przed Angular 4.3:

fileChange(event) { 
    let files = event.target.files; 
     if (files.length > 0) { 
     let formData: FormData = new FormData(); 
     for (let file of files) { 
      formData.append('files', file, file.name); 
     } 
     let headers = new Headers(); 
     headers.set('Accept', 'application/json'); 
     let options = new RequestOptions({ headers: headers }); 
     this.http.post(uploadURL, formData, options) 
      .map(res => res.json()) 
      .catch(error => Observable.throw(error)) 
      .subscribe(
      data => { 
       // Consume Files 
       // .. 
       console.log('uploaded and processed files'); 
      }, 
      error => console.log(error), 
      () => { 
       this.sleep(1000).then(() => 
        // .. Post Upload Delayed Action 
       ) 
      }); 
    } 
} 
+0

To właśnie dla mnie zadziałało.Dziękuję bardzo! – morrisbret

+0

Dla mnie brakowało ważnej linii: headers.set ('Accept', 'application/json'); –

+2

Należy zauważyć, że jest to dla starej wersji Http, która jest teraz (5.x) przestarzała. Powinieneś użyć 'HttpClient' z' @ angle/common/http'. –