问题
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