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