Search code examples
angularhttpurlencode

Preserving + (Plus Sign) in URLEncoded Http Post request


I have this function that I use for login requests.

private login(params: LoginParams): Promise<any> {
    const loginHeaders: HttpHeaders = new HttpHeaders()
        .set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
        .set('site', 'first');

    const loginCredentials = new HttpParams()
        .set('j_username', params.username)
        .set('j_password', params.password);

    const requestUrl = this.appConfig.baseUrl + 'restoftheurl';

    return this.http
        .post(requestUrl, loginCredentials.toString(),
            {headers: loginHeaders, responseType: 'text'})
        .toPromise();
  }

If the password has a plus sign (+) in it, it is encoded into a space sign and then the request fails being a bad credential. How do I preserve the plus sign? What am I doing wrong?


Solution

  • This is also an Angular issue (@angular/common/http)

    It will interpret the raw + sign as a replacement for a space.

    You can implement HttpParameterCodec into a simple encoder, for example:

    import {HttpParameterCodec} from "@angular/common/http";
    export class HttpUrlEncodingCodec implements HttpParameterCodec {
        encodeKey(k: string): string { return standardEncoding(k); }
        encodeValue(v: string): string { return standardEncoding(v); }
        decodeKey(k: string): string { return decodeURIComponent(k); }
        decodeValue(v: string) { return decodeURIComponent(v); }
    }
    function standardEncoding(v: string): string {
        return encodeURIComponent(v);
    }
    

    And then use it to get encoded correctly:

    const headers = new HttpHeaders({'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'});
    const params = new HttpParams({encoder: new HttpUrlEncodingCodec()});
    http.post(url, params, {headers: this.headers});