Search code examples
angulartypescriptpostangular-httpclientangular12

Can't make a x-www-form-urlencoded POST in Angular


I have a working POST and GET service and see no issues with CORS or such. However, I simply fail to mimic the call performed in Postman (where it works) and the only thing I can imagine is that I somehow set the x-www-form-urlencoded format incorrectly. Googling for examples gave me a lot of Spanish and Chinese sites for some reason. Copying examples from there, didn't resolve anything, though.

getToken(code: string): Observable<any> {

  let url = "https://localhost:44301/connect/token";

  let payload = {
    client_id: "awesome_client",
    client_secret: "HakunaMatata",
    redirect_uri: "http://localhost:44304/page01",
    code: code,
    grant_type: "authorization_code"
  };

  let headers = { "Content-Type": "x-www-form-urlencoded" };
  let options = { headers: headers };
  
  return this.http.post<any>(url, payload, options);
}

I understand there's some changes in Angular 12 so I tried a different version (also based on googling and examples). Same problem.

getToken(code: string): Observable<any> {
  ...
  return this.http.post<any>(
    url,
    payload.toString(),
    {
      headers: new HttpHeaders()
        .set('Content-Type', 'application/x-www-form-urlencoded')
    });
}

I simply fail to see what I'm missing. Postman produces expected result (body/x-www enabled).

https://localhost:44301/connect/token
client_id:awesome_client
client_secret:HakunaMatata
redirect_uri:http://localhost:44304/page01
code:4B822...
grant_type:authorization_code


Solution

  • When you use an objet as body of the HTTP Client, it will serialize it to json. If you want to send your data as x-www-form-urlencoded you need to use an HttpParams as body.

      getToken(code: string) {
        let url = 'https://localhost:44301/connect/token';
    
        let param = {
          client_id: 'awesome_client',
          client_secret: 'HakunaMatata',
          redirect_uri: 'http://localhost:44304/page01',
          code: code,
          grant_type: 'authorization_code'
        };
        var payload = new HttpParams({ fromObject: param });
    
        let headers = { 'Content-Type': 'x-www-form-urlencoded' };
        let options = { headers: headers };
    
        return this.http.post<any>(url, payload, options);
      }