2016-02-04 202 views
62

我試圖做一個POST請求,但我不能得到它的工作:Angular2 - HTTP POST請求參數

testRequest() { 
     var body = 'username=myusername?password=mypassword'; 
     var headers = new Headers(); 
     headers.append('Content-Type', 'application/x-www-form-urlencoded'); 

     this.http 
     .post('/api', 
      body, { 
      headers: headers 
      }) 
      .subscribe(data => { 
       alert('ok'); 
      }, error => { 
       console.log(JSON.stringify(error.json())); 
      }); 
} 

我基本上要複製這個HTTP請求(不阿賈克斯)就像是起源通過HTML表單:

網址:/ API

PARAMS:用戶名和密碼

+0

看看此http://計算器。 com/a/34758630/5043867和http://stackoverflow.com/a/34823818/5043867這將解釋所有關於POST請求的深入! –

+0

@PardeepJain我不想要使用API​​。只是爲了模擬由HTML表單發起的POST。 – Christopher

+0

也在這裏檢查,發佈帶有'user_name'和'password'的文件,https:// stackoverflow。com/a/45879409/2803344 – Belter

回答

27

我覺得身體不是一個application/x-www-form-urlencoded內容類型正確。您可以嘗試使用此:

var body = 'username=myusername&password=mypassword'; 

希望它可以幫助你, 蒂埃裏

+0

yes與標題中的內容類型一致,它是以「舊方式」而不是json字符串傳遞值的唯一解決方案 –

+0

這不是一個好答案。改用URLSearchParams,就像下面提到的更多upvotes一樣。 – Mick

+0

對於來自谷歌搜索未來的人來說,這不是最好的答案(Thierry沒有犯法!你的回答在技術上是正確的:))。 V斯托科夫的[答案](https://stackoverflow.com/a/41381299/239168)迄今爲止是最準確的。附:確保從「@ angular/http」'導入{URLSearchParams},而不是默認的導入{1},因此1)不需要對其執行'.toString',2)不需要設置內容類型。 Angular會自動爲您推斷它(請參閱https://github.com/angular/angular/blob/4.4.4/packages/http/src/static_request.ts#L134) –

-2

我降落在這裏的時候,我試圖做類似的事情。對於應用程序/ x-WWW的形式urlencoded的內容類型,你可以嘗試用這個身體:

var body = 'username' =myusername & 'password'=mypassword; 

你試着做分配到體將是一個字符串值是什麼。的

+0

這贏了正在工作 –

+0

正如Joshua指出的那樣,這不是有效的JavaScript,也不是TypeScript。我認爲你的意思完全是目前接受的答案。 –

77

更新Angualar 4.3+

現在我們可以用HttpClient代替Http

指南是here

示例代碼

const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded') 
const body = new HttpParams().set('username', USERNAME).set('password', PASSWORD); 
http 
    .post('/api', body, { 
    headers: myheader), 
    }) 
    .subscribe(); 

棄用

或者你可以這樣做:

let urlSearchParams = new URLSearchParams(); 
urlSearchParams.append('username', username); 
urlSearchParams.append('password', password); 
let body = urlSearchParams.toString() 

消息:十月/ 2017年

angular4 +,我們不需要headers,或.toString()東西。相反,你可以像下面的例子

import { URLSearchParams } from '@angular/http'; 

POST/PUT方法

let urlSearchParams = new URLSearchParams(); 
urlSearchParams.append('username', username); 
urlSearchParams.append('password', password); 
this.http.post('/api', urlSearchParams).subscribe(
     data => { 
     alert('ok'); 
     }, 
     error => { 
     console.log(JSON.stringify(error.json())); 
     } 
    ) 

GET/DELETE方法

let urlSearchParams = new URLSearchParams(); 
    urlSearchParams.append('username', username); 
    urlSearchParams.append('password', password); 
    this.http.get('/api', { search: urlSearchParams }).subscribe(
     data => { 
     alert('ok'); 
     }, 
     error => { 
     console.log(JSON.stringify(error.json())); 
     } 
    ) 

對於JSON application/json內容類型

this.http.post('/api', 
     JSON.stringify({ 
     username: username, 
     password: password, 
     })).subscribe(
     data => { 
     alert('ok'); 
     }, 
     error => { 
     console.log(JSON.stringify(error.json())); 
     } 
    ) 
+4

這應該是公認的答案。 – user623396

+13

不要忘記從「angular2/http」' –

+10

導入URLSearchParams類'import {URLSearchParams}我的導入看起來不同:從'@ angular/http'導入{URLSearchParams}; – dang

6

所以只是爲了讓它成爲一個compl ETE答案:

login(username, password) { 
     var headers = new Headers(); 
     headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
     let urlSearchParams = new URLSearchParams(); 
     urlSearchParams.append('username', username); 
     urlSearchParams.append('password', password); 
     let body = urlSearchParams.toString() 
     return this.http.post('http://localHost:3000/users/login', body, {headers:headers}) 
      .map((response: Response) => { 
       // login successful if there's a jwt token in the response 
       console.log(response); 
       var body = response.json(); 
       console.log(body); 
       if (body.response){ 
        let user = response.json(); 
        if (user && user.token) { 
         // store user details and jwt token in local storage to keep user logged in between page refreshes 
         localStorage.setItem('currentUser', JSON.stringify(user)); 
        } 
       } 
       else{ 
        return body; 
       } 
      }); 
    } 
+1

[ts ] 類型'{headers:RequestOptions; }'不能分配給類型爲'RequestOptionsArgs'的參數 –

+2

@Sonic Soul它只是:.. post('/ api',body,headers)... {}不包含標題 – Guenther

39

在以後的版本中Angular2的,不需要手動設置Content-Type頭,如果你傳遞正確類型的對象作爲body編碼體。

你根本可以做到這一點

import { URLSearchParams } from "@angular/http" 


testRequest() { 
    let data = new URLSearchParams(); 
    data.append('username', username); 
    data.append('password', password); 

    this.http 
    .post('/api', data) 
     .subscribe(data => { 
      alert('ok'); 
     }, error => { 
      console.log(error.json()); 
     }); 
} 

這樣的角度將編碼的身體爲你,並會設置正確的Content-Type頭。

P.S.不要忘記從@angular/http導入URLSearchParams,否則它將無法工作。

+0

你知道在哪個版本中添加? – britter

+0

我不知道它在哪個版本中添加,但在2.3.1及更高版本中它可以工作。 –

+2

@VStoykov它不工作,你必須在參數上.toString(),你必須指定的內容類型,我使用角4.0.3 – lll

0

我是用多個參數具有與每一個方法的問題,但它工作得很好用單一的對象

API:

[HttpPut] 
    [Route("addfeeratevalue")] 
    public object AddFeeRateValue(MyValeObject val) 

角:

var o = {ID:rateId, AMOUNT_TO: amountTo, VALUE: value}; 
return this.http.put('/api/ctrl/mymethod', JSON.stringify(o), this.getPutHeaders()); 


private getPutHeaders(){ 
    let headers = new Headers(); 
    headers.append('Content-Type', 'application/json'); 
    return new RequestOptions({ 
     headers: headers 
     , withCredentials: true // optional when using windows auth 
    }); 
} 
+0

OP的問題是application/x-www-form-urlencoded的內容類型,你的回答是一個完全不同的問題。 –

2

如果有人掙扎角度版本4+(我的是4.3.6)。這是爲我工作的示例代碼。

首先添加所需的進口

import { Http, Headers, Response, URLSearchParams } from '@angular/http'; 

那麼對於API函數。這是一個登錄樣本,可以根據您的需要進行更改。

login(username: string, password: string) { 
    var headers = new Headers(); 
    headers.append('Content-Type', 'application/x-www-form-urlencoded'); 
    let urlSearchParams = new URLSearchParams(); 
    urlSearchParams.append('email', username); 
    urlSearchParams.append('password', password); 
    let body = urlSearchParams.toString() 

    return this.http.post('http://localhost:3000/api/v1/login', body, {headers: headers}) 
     .map((response: Response) => { 
      // login successful if user.status = success in the response 
      let user = response.json(); 
      console.log(user.status) 
      if (user && "success" == user.status) { 
       // store user details and jwt token in local storage to keep user logged in between page refreshes 
       localStorage.setItem('currentUser', JSON.stringify(user.data)); 
      } 
     }); 
} 
+0

適合我!謝謝! –

2

這些答案都已經過時了那些利用HttpClient的,而不是HTTP。我開始瘋狂地想:「我已經完成了URLSearchParams的導入,但是如果沒有.toString()和顯式頭文件,它仍然不起作用!」

隨着HttpClient的,使用的HttpParams代替URLSearchParams並注意body = body.append()語法在體內實現多PARAMS因爲我們有一個不可變對象的工作:

login(userName: string, password: string): Promise<boolean> { 
    if (!userName || !password) { 
     return Promise.resolve(false); 
    } 

    let body: HttpParams = new HttpParams(); 
    body = body.append('grant_type', 'password'); 
    body = body.append('username', userName); 
    body = body.append('password', password); 

    return this.http.post(this.url, body) 
     .map(res => { 
     if (res) {   
      return true; 
     } 
     return false; 
     }) 
     .toPromise(); 
    }