2016-02-04 218 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(); 
    }