javascript - data - Как заставить Angular2 POST использовать x-www-form-urlencoded



javascript post запрос (4)

У меня есть проект, который должен использовать Angular2 (окончательный вариант) для публикации на старом унаследованном сервере Tomcat 7, предоставляющем API-интерфейс REST-ish с использованием страниц .jsp.

Это работало нормально, когда проект представлял собой простое приложение JQuery, выполняющее запросы AJAX. Тем не менее, масштабы проекта выросли так, что его необходимо будет переписать с использованием более современных рамок. Angular2 выглядит фантастически для этой работы, за одним исключением: он отказывается выполнять запросы POST, используя что-либо, кроме как данные формы, которые API не извлекает. API ожидает, что все будет urlencoded, полагаясь на синтаксис Java request.getParameter("param") для извлечения отдельных полей.

Это отрывок из моего 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));
                }
            }
        );
    }
}

Независимо от того, какой я установил тип содержимого заголовка, он всегда заканчивается как не закодированные данные формы. Это не в честь заголовка, который я устанавливаю.

кто-нибудь еще сталкивался с этим? Как вы собираетесь использовать Angular2 для POST-данных в формате, который может быть прочитан старым Java API с помощью request.getParameter("param") ?

Изменить : Для тех, кто найдет это в будущем, решение на самом деле очень просто. Установите тело сообщения следующим образом:

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

Смотрите пример Брэда ниже.

https://ffff65535.com


Вот что сработало для меня с Angular 7:

const payload = new HttpParams()
  .set('username', username)
  .set('password', password);

this.http.post(url, payload);

Нет необходимости явно устанавливать заголовок при таком подходе.

Обратите внимание, что объект HttpParams является неизменным. Таким образом, выполнение чего-то вроде следующего не будет работать, оно даст вам пустое тело:

const payload = new HttpParams();
payload.set('username', username);
payload.set('password', password);

this.http.post(url, payload);

Вы можете сделать это, используя URLSearchParams в качестве тела запроса, и angular автоматически установит тип содержимого на application/x-www-form-urlencoded и правильно application/x-www-form-urlencoded тело.

let body = new URLSearchParams();
body.set('username', username);
body.set('password', password);

this.http.post(this.loginUrl, body).map(...);

Причина, по которой он в настоящее время не работает для вас, заключается в том, что вы не кодируете данные тела в правильном формате и неправильно настраиваете параметры заголовка.

Вам нужно закодировать тело следующим образом:

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

Вам нужно установить параметры заголовка следующим образом:

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

Для тех, кто все еще ищет ответ, вот как я решил его с помощью Angular 5 и 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);

НЕ устанавливайте заголовок Content-Type, угловой исправит это для вас!


Я нашел это решение после нескольких часов работы над этим вопросом.

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);
  }));

}





angular