Angular2-Http POST请求参数


91

我正在尝试发出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请求(而不是ajax),就像它是由html表单发起的一样:

网址:/ api

参数:用户名和密码



@PardeepJain我不是要使用API​​。只是为了模拟html表单产生的POST。
Christopher

还要在此处检查,使用user_name和发布文件passwordstackoverflow.com
45879409/2803344

Answers:


49

我认为该正文不适用于application/x-www-form-urlencoded内容类型。您可以尝试使用此方法:

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

希望对您有帮助,蒂埃里


是的,在标头中使用该内容类型,它是唯一以“旧方式”传递值而不是json字符串的解决方案
Nather Webber

这不是一个好答案。改用URLSearchParams,如下面提到的,带有更多赞誉。
米克,

对于将来来自Google搜索的人们来说,这不是最好的答案(蒂埃里(Thierry)没有冒犯!从技术上来说,您的答案仍然是正确的:))。到目前为止,V Stoykov的答案是最准确的。ps确保 import { URLSearchParams } from "@angular/http"使用默认值而不是默认值,因此1)您不需要对其进行操作.toString,并且2)您不需要设置内容类型。角将自动推断它为您(见github.com/angular/angular/blob/4.4.4/packages/http/src/...
伊兰棉兰

嗨!如果我想通过标头->内容类型(例如'application / json')传递邮递服务,我需要在正文中传递....我正试图传递json对象,但它无法正常工作...
VjyV

107

更新为Angualar 4.3+

现在我们可以HttpClient代替Http

指南在这里

样例代码

const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
let body = new HttpParams();
body = body.set('username', USERNAME);
body = body.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年10月

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/jsonContent-Type

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

14
别忘了导入URLSearchParams类import { URLSearchParams } from "angular2/http"
Sebastian Hernandez

10
我的导入看起来有所不同:从'@ angular / http'导入{URLSearchParams};
当当

但是,没有更简单的方法来发送表单对象吗?我没有看到任何使用URLSearchParams()来发送具有宁静背景的帖子的教程。他们怎么办?返回this.http.post(this.actionUrl,body,{headers:this.headers}).map((response:Response)=> response.json()).catch(this.handleError);
stackdave

布尔值如何工作?收到一条错误消息,说我不能添加布尔值或数字,只能添加字符串(追加)
JohnAndrews 17/02/23

关于布尔,也许这个话题可以帮助您stackoverflow.com/questions/14774907/...
弗兰克阮

41

在更高版本的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());
      });
}

这样,angular将为您编码主体并设置正确的Content-Type标头。

PS不要忘记从中导入URLSearchParams@angular/http否则它将无法正常工作。


2
@VStoykov它不起作用,您必须在参数上使用.toString(),并且必须指定内容类型,并且我使用angular 4.0.3
Konrad

1
@ i'myourhuckleberry即使在4.0.3上也应该可以使用。看看源代码github.com/angular/angular/blob/4.0.3/packages/http/src/…–
VStoykov

1
@VStoykov它对我不起作用,我已经在Github上将其报告为错误
Konrad

1
好。Nvm我必须从“ @ angular / http”导入它,否则它可以识别类型,但不是angular的类型。
Konrad

1
@ i'myourhuckleberry导入是我示例中的第一行,但您可能错过了它。从浏览器的内置类型中,您可以使用FormData,并且angular也将被设置Content-Type为可以使用multipart/form-data
VStoykov '17

10

因此,仅作一个完整的答案即可:

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]类型'{标题的参数:RequestOptions; }'不可分配给'RequestOptionsArgs'类型的参数
Sonic Soul

2
@Sonic Soul只是:.. post('/ api',body,headers)...在标题周围没有{}
Guenther

5

对于那些使用HttpClient而不是Http的用户,这些答案都是过时的。我开始发疯了,“我已经完成了URLSearchParams的导入,但是如果没有.toString()和显式标头,它仍然无法工作!”

使用HttpClient时,请使用HttpParams而不是URLSearchParams并注意body = body.append()语法,以在体内实现多个参数,因为我们正在使用不可变的对象:

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

感谢上述解决方案。但是,当运行ng build --prod时,我的身体参数看起来像“ {” params“:{” rawParams“:”“,” queryEncoder“:{},” paramsMap“:{}}}:”。有没有解决的办法。
Hemanth Poluru

4

如果有人在角版本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

在使用多个参数的每种方法中,我都遇到了问题,但是对于单个对象它却可以很好地工作

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

1
OP的问题是application / x-www-form-urlencoded的内容类型,您的答案是完全不同的问题。
克里斯蒂安·乌尔布里希

0
angular: 
    MethodName(stringValue: any): Observable<any> {
    let params = new HttpParams();
    params = params.append('categoryName', stringValue);

    return this.http.post('yoururl', '', {
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      params: params,
      responseType: "json"
    })
  }

api:   
  [HttpPost("[action]")]
  public object Method(string categoryName)

嗨,欢迎来到Stackoverflow。感谢您回答这个问题,但是对于OP或以后遇到此问题的任何人来说,仅发布一段代码很难理解。您是否可以编辑问题并给出(简短的)解释您解决了什么问题以及如何解决的问题,以帮助我们更好地理解您的解决方案?
Plutian

1
@Plutian,您好,当我在post request的第二个参数上传递值时,它向我返回了api上的空值,因此我将该第二个参数传递为空字符串,并在第3个参数的params属性上传递了值,因此该方法对我
有用

-2

当我尝试做类似的事情时,我降落在这里。对于application / x-www-form-urlencoded内容类型,您可以尝试将其用于正文:

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

您尝试执行的操作将赋值为body的字符串。


正如Joshua指出的那样,这既不是有效的JavaScript也不是TypeScript。我认为您的意思恰好是当前接受的答案。
克里斯蒂安·乌尔布里希
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.