web-dev-qa-db-fra.com

Angular url plus signe convertissant en espace

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

% 2 se réfère à l'espace. Comment puis-je empêcher cette conversion?

29
Manwal

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;
      });
    }
  ])
2
Manwal

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
    }
]
19
Piotr Korlaga

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);
15
Faisal

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.

10
abahet

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:

  • Encodez le paramètre en encodage en base64, ainsi aucun caractère spécial ne pourra casser votre application, mais vous devrez le gérer également sur la partie réceptrice (décodage).
  • Une solution plus simple consisterait, avant de frapper l'URL, à remplacer tous les signes + par% 2B. De cette façon, l’autre partie sera capable de le décoder normalement, sans avoir besoin d’une routine spéciale.

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?

4
Aleksandar

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