Preserving + (Plus Sign) in URLEncoded Http Post request

末鹿安然 提交于 2020-01-24 11:12:09

问题


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?


回答1:


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



回答2:


Just use encodeURIComponent to encode the password before sending it.

private login(params: LoginParams): Promise < any > {

  ...

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

  ...
}

NOTE: On your API end, you'll have to use decodeURIComponent(yourPasswordParam) to get the actual password.

UPDATE:

Just try it right here and see what it gives on encoding:

var encodedUsername = encodeURIComponent('mclovin+');
console.log('Encoding Username gives: ', encodedUsername);
console.log('NOT mclovin%252B');

var encodedPassword = encodeURIComponent('fogell+');
console.log('Encoding Password gives: ', encodedPassword);
console.log('NOT fogell%252B');



回答3:


If you are trying to send it as part of URL, this has to be encoded using encodeURIComponent.

Seeing your code you are adding the password and username in HTTP params which will be shown in request url.

If you do not want to show username and password as part of url query string, you can send it as request body for the http call and you will, not need to do encodeURIComponent.

EX:console.log(encodeURIComponent('?x=test'));

console.log(encodeURIComponent('+test'));


来源:https://stackoverflow.com/questions/53546691/preserving-plus-sign-in-urlencoded-http-post-request

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!