web-dev-qa-db-ja.com

Angular urlプラス記号をスペースに変換

私はangularアプリケーションにプラス記号を渡したい+のようなクエリ文字列があります:

http://localhost:3000/page?name=xyz+manwal

このURLにアクセスすると、次のように変換されます。

http://localhost:3000/page?name=xyz%20manwal

%2はスペースを参照します。この変換を防ぐにはどうすればよいですか?

29
Manwal

私は解決策を見つけ、将来の参考のためにそれを投稿しました。 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;
      });
    }
  ])
2
Manwal

これを修正するインターセプターを追加することで、デフォルトの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
    }
]
19
Piotr Korlaga

これはよくある問題です。 _+_文字は、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);
_
15
Faisal

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

これが役立つことを願っています。

10
abahet

これは非常に一般的な問題です。通常はapplication/x-www-form-urlencodedリクエストで渡すことができます。他のリクエストは+を正しく解析できません。彼らは常に%2Bではなく%20にそれを解析します。

クエリパラメータを手動で操作する必要があります。2つの方法があります。

  • パラメーターをbase64エンコードにエンコードします。これにより、特殊文字がアプリケーションを破壊することはありませんが、受信側でも処理する必要があります(デコード)。
  • 簡単な解決策は、URLにアクセスする前に、すべての+記号を%2Bに置き換えることです。これにより、反対側は特別なルーチンを必要とせずに通常どおりデコードできます。

詳細については、次のスタックオーバーフローの質問を参照する必要があります Android:ハウツーパースURL文字列にURIオブジェクト? および URL文字エンコード: +または%20?

4
Aleksandar

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');
1
Wellspring