私はangularアプリケーションにプラス記号を渡したい+のようなクエリ文字列があります:
http://localhost:3000/page?name=xyz+manwal
このURLにアクセスすると、次のように変換されます。
http://localhost:3000/page?name=xyz%20manwal
%2はスペースを参照します。この変換を防ぐにはどうすればよいですか?
私は解決策を見つけ、将来の参考のためにそれを投稿しました。 Angular jsは+
にサインイン %2B
。
次のコードはそれを防ぎました:
.config([
'$provide', function($provide) {
$provide.decorator('$browser', function($delegate) {
let superUrl = $delegate.url;
$delegate.url = (url, replace) => {
if(url !== undefined) {
return superUrl(url.replace(/\%2B/g,"+"), replace);
} else {
return superUrl().replace(/\+/g,"%2B");
}
};
return $delegate;
});
}
])
これを修正するインターセプターを追加することで、デフォルトのangularエンコーディングをオーバーライドできます。
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: [
{
provide: HTTP_INTERCEPTORS,
useClass: EncodeHttpParamsInterceptor,
multi: true
}
]
これはよくある問題です。 _+
_文字は、2つの単語を区切るためにURLで使用されます。パラメーター値で_+
_文字を使用するには、URLの一部として追加する前にパラメーター値をエンコードする必要があります。 Javascript/TypeScriptは、その特定の目的のためにencodeURI()
関数を提供します。
URLエンコードは、文字をインターネット経由で送信できる形式に変換します。 [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
これが役立つことを願っています。
これは非常に一般的な問題です。通常はapplication/x-www-form-urlencodedリクエストで渡すことができます。他のリクエストは+を正しく解析できません。彼らは常に%2Bではなく%20にそれを解析します。
クエリパラメータを手動で操作する必要があります。2つの方法があります。
詳細については、次のスタックオーバーフローの質問を参照する必要があります Android:ハウツーパースURL文字列にURIオブジェクト? および URL文字エンコード: +または%20?
Angular v6.1.10、1つのスポットで「+」符号エンコーディングを修正する必要がある場合、これは私のために働いたものです。
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');