在 URLEncoded Http Post 请求中保留 +(加号)
Preserving + (Plus Sign) in URLEncoded Http Post request
我有这个用于登录请求的功能。
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();
}
如果密码中有加号 (+),它会被编码为 space 符号,然后请求将失败,这是一个错误的凭据。如何保留加号?我做错了什么?
如果您尝试将其作为 URL 的一部分发送,则必须使用 encodeURIComponent
.
对其进行编码
看到你的代码,你在 HTTP 参数中添加了密码和用户名,这将在请求中显示 url。
如果您不想将用户名和密码显示为 url 查询字符串的一部分,您可以将其作为请求正文发送给 http 调用,您不需要这样做 encodeURIComponent
.
EX:console.log(encodeURIComponent('?x=test'));
console.log(encodeURIComponent('+test'));
只需在发送前使用encodeURIComponent
对密码进行编码。
private login(params: LoginParams): Promise < any > {
...
const loginCredentials = new HttpParams()
.set('j_username', params.username)
.set('j_password', encodeURIComponent(params.password));
...
}
注意: 在您的 API 端,您必须使用 decodeURIComponent(yourPasswordParam)
来获取实际密码。
更新:
就在这里尝试一下,看看它在编码方面的作用:
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');
这也是一个 Angular 问题 (@angular/common/http)
它将原始 + 符号解释为 space 的替代。
你可以将HttpParameterCodec实现成一个简单的编码器,例如:
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);
}
然后用它来正确编码:
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});
我有这个用于登录请求的功能。
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();
}
如果密码中有加号 (+),它会被编码为 space 符号,然后请求将失败,这是一个错误的凭据。如何保留加号?我做错了什么?
如果您尝试将其作为 URL 的一部分发送,则必须使用 encodeURIComponent
.
看到你的代码,你在 HTTP 参数中添加了密码和用户名,这将在请求中显示 url。
如果您不想将用户名和密码显示为 url 查询字符串的一部分,您可以将其作为请求正文发送给 http 调用,您不需要这样做 encodeURIComponent
.
EX:console.log(encodeURIComponent('?x=test'));
console.log(encodeURIComponent('+test'));
只需在发送前使用encodeURIComponent
对密码进行编码。
private login(params: LoginParams): Promise < any > {
...
const loginCredentials = new HttpParams()
.set('j_username', params.username)
.set('j_password', encodeURIComponent(params.password));
...
}
注意: 在您的 API 端,您必须使用 decodeURIComponent(yourPasswordParam)
来获取实际密码。
更新:
就在这里尝试一下,看看它在编码方面的作用:
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');
这也是一个 Angular 问题 (@angular/common/http)
它将原始 + 符号解释为 space 的替代。
你可以将HttpParameterCodec实现成一个简单的编码器,例如:
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);
}
然后用它来正确编码:
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});