Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 507
Anjil Dhamala Avatar asked Nov 29 '18 20:11

Anjil Dhamala


People also ask

How to encode plus sign in URL?

If you want a plus + symbol in the body you have to encode it as 2B . Literally as %2B ? Yes, %2B is what you want!

Can URL have plus sign?

Generally speaking, the plus sign is used as shorthand for a space in query parameters, but while it can be used in such a way in URLs, it isn't a good idea. The plus sign is sometimes transformed into a space or to “%20” which can cause problems for the spiders crawling your site, hence causing issues with indexation.

Can we pass special characters in URL?

For instance, the "#" character needs to be encoded because it has a special meaning of that of an html anchor. The <space> character needs to be encoded because it is not a valid URL character. Also, some characters, such as "~" might not transport properly across the internet.

How do you escape space in URL?

URLs cannot contain spaces. URL encoding normally replaces a space with a plus (+) sign or with %20.


1 Answers

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});
like image 176
Vy Nguyen Avatar answered Oct 09 '22 11:10

Vy Nguyen