J'ai angular application où je veux passer le signe plus + dans la chaîne de requête comme:
http://localhost:3000/page?name=xyz+manwal
Lorsque je clique sur cette URL, sa conversion en:
http://localhost:3000/page?name=xyz%20manwal
Où % 2 se réfère à l'espace. Comment puis-je empêcher cette conversion?
J'ai trouvé la solution et l'affiche pour référence future. Angular js était en train de convertir +
vous connecter à %2B
.
Le code suivant a empêché que:
.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;
});
}
])
Vous pouvez écraser l'encodage par défaut angular avec l'ajout d'Interceptor qui corrige ceci:
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);
}
}
et le déclarer dans la section des fournisseurs de dans app.module.ts
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: EncodeHttpParamsInterceptor,
multi: true
}
]
C'est un problème commun. Le caractère +
Est utilisé par l'URL pour séparer deux mots. Pour utiliser le caractère +
Dans les valeurs de paramètre, vous devez coder vos valeurs de paramètre avant de les ajouter dans l'URL. Javascript/TypeScript fournit une fonction encodeURI()
à cette fin.
Le codage d'URL convertit les caractères dans un format pouvant être transmis sur Internet. [Référence de w3Schools]
Voici comment vous pouvez résoudre ce problème:
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 }`;
De la même manière, vous pouvez décoder les paramètres en utilisant la méthode decodeURI()
.
let decodedValue = decodeURI(encodedValue);
Dans Angular 5.2.7+, le "+" est remplacé par un espace "" dans une chaîne de requête.
Voici le commit correspondant: correctif (routeur): sérialisation de l'URL fixe
Si vous souhaitez modifier ce comportement et remplacer le "+" par "% 2B", vous pouvez créer un sérialiseur d'URL personnalisé et le fournir dans les fournisseurs 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
L'URL sera convertie en:
http://localhost:3000/page?name=xyz%2Bmanwal
J'espère que cela aidera.
C'est un problème assez commun. Vous pouvez le transmettre normalement dans la requête application/x-www-form-urlencoded. Aucune autre requête ne pourra analyser correctement +. Ils l’analyseront toujours dans% 20 au lieu de% 2B.
Vous auriez besoin de manipuler manuellement le paramètre de requête, il y a 2 façons:
Pour plus d'informations, vous devez vous reporter aux questions suivantes concernant le dépassement de pile Android: comment analyser une chaîne d'URL avec des espaces dans un objet URI? et RL codant le caractère d'espace: + ou% 20?
Dans Angular v6.1.10, si vous avez juste besoin de corriger le codage du signe "+" à un endroit donné, c’est ce qui a fonctionné pour moi.
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);
}
J'ai trouvé que si vous essayez de remplacer les signes "+" lors de l'initialisation de l'objet httpParams
, cela ne fonctionne pas. Vous devez faire le remplacement après avoir converti httpParams
en chaîne, comme indiqué sur cette ligne:
let url = BASE_URL + "/select?" + httpParams.toString().replace(/\+/gi, '%2B');