1. ホーム
  2. javascript

[解決済み] Angular2のPOSTをx-www-form-urlencodedで強制する方法

2023-05-20 22:59:30

質問

私は、Angular2(最終)を使用して、古い、レガシーTomcat 7サーバーに投稿し、.jspページを使用してややREST的なAPIを提供する必要があるプロジェクトを持っています。

プロジェクトが AJAX リクエストを実行する単純な JQuery アプリケーションであったときは、これはうまくいきました。しかし、プロジェクトの範囲が拡大したため、より近代的なフレームワークを使用して書き直す必要が出てきました。Angular2はこのプロジェクトに最適なフレームワークですが、1つだけ例外があります。それは、APIが抽出しないフォームデータ以外のオプションを使ったPOSTリクエストの実行を拒否することです。APIはすべてがurlencodeされることを期待し、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が古いJava APIで読み取れる形式でデータをPOSTするために request.getParameter("param") ?

編集 : 今後これを発見した人のために、解決策は実はとても簡単です。投稿の本文をこのように設定します。

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

以下のBradの例を見てください。

どのように解決するのですか?

2020年6月に更新しました。この回答は4年前のもので、AngularのAPI変更により無効となりました。現在のバージョンのアプローチについては、より新しい回答を参照してください。


これを行うには URLSearchParams をリクエストのボディとして使用すると、angular は自動的にコンテンツタイプを 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(...);