我有 angular 应用程序,我想在查询字符串中传递加号+,例如:
http://localhost:3000/page?name=xyz+manwal
当我点击这个 URL 时,它会转换为:
http://localhost:3000/page?name=xyz%20manwal
其中%20指的是空间。如何防止这种转换?
我有 angular 应用程序,我想在查询字符串中传递加号+,例如:
http://localhost:3000/page?name=xyz+manwal
当我点击这个 URL 时,它会转换为:
http://localhost:3000/page?name=xyz%20manwal
其中%20指的是空间。如何防止这种转换?
您可以通过添加修复此问题的拦截器来覆盖默认角度编码:
import { HttpInterceptor, HttpRequest, HttpEvent, HttpHandler, HttpParams, HttpParameterCodec } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs";
@Injectable()
export class EncodeHttpParamsInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const params = new HttpParams({encoder: new CustomEncoder(), fromString: req.params.toString()});
return next.handle(req.clone({params}));
}
}
class CustomEncoder implements HttpParameterCodec {
encodeKey(key: string): string {
return encodeURIComponent(key);
}
encodeValue(value: string): string {
return encodeURIComponent(value);
}
decodeKey(key: string): string {
return decodeURIComponent(key);
}
decodeValue(value: string): string {
return decodeURIComponent(value);
}
}
并在 app.module.ts 的 providers 部分声明它
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: EncodeHttpParamsInterceptor,
multi: true
}
]
这是一个常见的问题。+
URL 使用该字符来分隔两个单词。为了+
在参数值中使用该字符,您需要在将参数值添加为 URL 的一部分之前对其进行编码。Javascript / TypeScriptencodeURI()
为该特定目的提供了一个函数。
URL 编码将字符转换为可以通过 Internet 传输的格式。[w3Schools 参考]
以下是解决此问题的方法:
let encodedName = encodeURI('xyz+manwal');
let encodedURI = 'http://localhost:3000/page?name='+encodedName;
//.. OR using string interpolation
let encodedURI = `http://localhost:3000/page?name=${ encodedName }`;
同样,您可以使用decodeURI()
方法对参数进行解码。
let decodedValue = decodeURI(encodedValue);
在 Angular 5.2.7+ 中,查询字符串中的“+”被替换为空格“”。
这是相应的提交:fix(router): fix URL serialization
如果您想更改此行为并将“+”替换为“%2B”,您可以创建一个自定义 url 序列化程序并在 AppModule 提供程序中提供它。
import { DefaultUrlSerializer, UrlSerializer, UrlTree } from '@angular/router';
export default class CustomUrlSerializer implements UrlSerializer {
private _defaultUrlSerializer: DefaultUrlSerializer = new DefaultUrlSerializer();
parse(url: string): UrlTree {
// Encode "+" to "%2B"
url = url.replace(/\+/gi, '%2B');
// Use the default serializer.
return this._defaultUrlSerializer.parse(url);
}
serialize(tree: UrlTree): string {
return this._defaultUrlSerializer.serialize(tree).replace(/\+/gi, '%2B');
}
}
@NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
AppRoutingModule
],
declarations: [
AppComponent
],
providers: [
{ provide: UrlSerializer, useClass: CustomUrlSerializer }
],
entryComponents: [],
bootstrap: [AppComponent]
})
export class AppModule {
}
http://localhost:3000/page?name=xyz+manwal
URL 将被转换为:
http://localhost:3000/page?name=xyz%2Bmanwal
希望这会有所帮助。
在 Angular v6.1.10 中,如果您只需要在一处修复“+”号编码,这对我有用。
getPerson(data: Person) {
const httpParams = new HttpParams({
fromObject: {
id: data.id,
name: data.name,
other: "xyz+manwal"
}
});
// manually encode all "+" characters from the person details
let url = BASE_URL + "/select?" + httpParams.toString().replace(/\+/gi, '%2B');
return this.http.get(url);
}
我发现如果您在初始化httpParams
对象时尝试替换“+”号,则它不起作用。您必须在转换httpParams
为字符串后进行替换,如这一行所示:
let url = BASE_URL + "/select?" + httpParams.toString().replace(/\+/gi, '%2B');
这是一个很常见的问题。您可以在 application/x-www-form-urlencoded 请求中正常传递它。没有其他请求将能够正确解析 +。他们将始终将其解析为 %20 而不是 %2B。
您需要手动操作查询参数,有两种方法:
有关更多信息,您应该参考以下堆栈溢出问题Android:如何将带有空格的 URL 字符串解析为 URI 对象?和URL 编码空格字符:+ 或 %20?