www urlencoded form example data application javascript angular

javascript - example - Cómo forzar a Angular2 a POST usando x-www-form-urlencoded



application x www form urlencoded httpclient angular (5)

Descubrí esta solución después de trabajar varias horas en este problema.

login(userName: string, password: string) { const headers = new Headers(); headers.append(''Accept'', ''application/json''); headers.append(''Content-Type'', ''application/x-www-form-urlencoded''); headers.append( ''No-Auth'', ''True''); const body = new URLSearchParams(); body.set(''username'', userName); body.set(''password'', password); body.set(''grant_type'', ''password''); return this.http.post( this.baseUrl + ''/token'' , body.toString() , { headers: headers } ) .pipe(map(res => res.json())) .pipe(map(res => { localStorage.setItem(''auth_token'', res.auth_token); return true; })) .pipe(catchError((error: any) => { return Observable.throw(error); }));

}

Tengo un proyecto que necesita usar Angular2 (final) para publicar en un servidor antiguo y antiguo de Tomcat 7 que proporciona una API algo REST-ish usando páginas .jsp.

Esto funcionó bien cuando el proyecto era solo una simple aplicación JQuery que realizaba solicitudes AJAX. Sin embargo, el alcance del proyecto ha crecido de tal manera que deberá reescribirse utilizando un marco más moderno. Angular2 se ve fantástico para el trabajo, con una excepción: se niega a realizar solicitudes POST utilizando cualquier opción, pero como datos de formulario, que la API no extrae. La API espera que todo se codifique por urlen, confiando en la sintaxis request.getParameter("param") Java para extraer campos individuales.

Este es un recorte de mi user.service.ts:

import { Injectable } from ''@angular/core''; import { Headers, Response, Http, RequestOptions } from ''@angular/http''; import { Observable } from ''rxjs/Observable''; import ''rxjs/add/operator/map''; @Injectable() export class UserService { private loggedIn = false; private loginUrl = ''http://localhost:8080/mpadmin/api/login.jsp''; private headers = new Headers({''Content-Type'': ''application/x-www-form-urlencoded''}); constructor(private http: Http) {} login(username, password) { return this.http.post(this.loginUrl, {''username'': username, ''password'': password}, this.headers) .map((response: Response) => { let user = response.json(); if (user) { localStorage.setItem(''currentUser'', JSON.stringify(user)); } } ); } }

No importa cuál sea el tipo de contenido del encabezado, siempre termina llegando como datos de formulario no codificados. No está honrando el encabezado que estoy configurando.

¿Alguien más ha encontrado esto? ¿Cómo se hace para forzar a Angular2 a enviar datos en un formato que puede leer una antigua API de Java utilizando request.getParameter("param") ?

Editar : Para cualquiera que encuentre esto en el futuro, la solución es realmente simple. Establece el cuerpo de la publicación de esta manera:

let body = `username=${username}&password=${password}`;`

Vea el ejemplo de Brad a continuación.


Esto es lo que funcionó para mí con Angular 7:

const payload = new HttpParams() .set(''username'', username) .set(''password'', password); this.http.post(url, payload);

No es necesario establecer explícitamente el encabezado con este enfoque.

Tenga en cuenta que el objeto HttpParams es inmutable. Entonces, hacer algo como lo siguiente no funcionará, le dará un cuerpo vacío:

const payload = new HttpParams(); payload.set(''username'', username); payload.set(''password'', password); this.http.post(url, payload);


Para Angular 4.3 + / 5 + (Nuevo HTTPClient) use lo siguiente:

let body = new URLSearchParams(); body.set(''user'', username); body.set(''password'', password); let options = { headers: new HttpHeaders().set(''Content-Type'', ''application/x-www-form-urlencoded'') }; this.http .post(''//yourUrl.com/login'', body.toString(), options) .subscribe(response => { //... });

Tenga en cuenta 3 cosas para que funcione como se esperaba:

  1. Use URLSearchParams para su cuerpo
  2. Convertir cuerpo a cadena
  3. Establecer el tipo de contenido del encabezado

Atención : los navegadores más antiguos necesitan un polyfill. npm i url-search-params-polyfill --save : npm i url-search-params-polyfill --save y luego agregué a polyfills.ts: import ''url-search-params-polyfill'';


Para aquellos que todavía buscan una respuesta, así es como lo resolví con Angular 5 y HttpClient:

const formData = new FormData(); // append your data formData.append(''myKey1'', ''some value 1''); formData.append(''myKey1'', ''some value 2''); formData.append(''myKey3'', true); this.httpClient.post(''apiPath'', formData);

¡ NO configure el encabezado Content-Type, angular lo solucionará por usted!


Puede hacerlo utilizando URLSearchParams como el cuerpo de la solicitud y angular establecerá automáticamente el tipo de contenido en application/x-www-form-urlencoded y codificará el cuerpo correctamente.

let body = new URLSearchParams(); body.set(''username'', username); body.set(''password'', password); this.http.post(this.loginUrl, body).map(...);

La razón por la que actualmente no funciona para usted es que no está codificando los datos del cuerpo en el formato correcto y no está configurando las opciones de encabezado correctamente.

Necesitas codificar el cuerpo así:

let body = `username=${username}&password=${password}`;

Debe configurar las opciones de encabezado de esta manera:

this.http.post(this.loginUrl, body, { headers: headers }).map(...);