Angular2-Http POSTリクエストパラメータ


91

POSTリクエストを作成しようとしていますが、機能しません。

testRequest() {
      var body = 'username=myusername?password=mypassword';
      var headers = new Headers();
      headers.append('Content-Type', 'application/x-www-form-urlencoded');

      this.http
        .post('/api',
          body, {
            headers: headers
          })
          .subscribe(data => {
                alert('ok');
          }, error => {
              console.log(JSON.stringify(error.json()));
          });
}

私は基本的に、このHTTPリクエスト(ajaxではありません)をHTMLフォームによって作成されたように複製したいと思います。

URL:/ api

パラメータ:ユーザー名とパスワード


このstackoverflow.com/a/34758630/5043867stackoverflow.com/a/34823818/5043867をご覧ください。これにより、POSTリクエストの詳細が説明されます。
Pardeep Jain、2016

@PardeepJain私はAPIを消費しようとはしていません。htmlフォームから発生したPOSTをシミュレートするだけです。
クリストファー

こちらもチェックして、user_nameとファイルを投稿してくださいpasswordstackoverflow.com
2803344

回答:


49

本文はapplication/x-www-form-urlencodedコンテンツタイプに対して正しくないと思います。あなたはこれを使ってみることができます:

var body = 'username=myusername&password=mypassword';

それがあなたを助けることを願っています、ティエリー


はい、ヘッダーにそのコンテンツタイプがある場合、json文字列の代わりに「古い方法」で値を渡す唯一のソリューションです
Nather Webber

これは良い答えではありません。代わりにURLSearchParamsを使用してください。
Mick

Google検索から来る将来の人々にとって、これは最良の答えではありません(Thierryを怒らせないでください!あなたの答えは技術的に正しいです:))。V Stoykovの答えはこれまでのところ最も正確です。ps import { URLSearchParams } from "@angular/http"はデフォルトのものではなく、必ず確認して ください。1).toStringオンにする必要はありません。2)コンテンツタイプを設定する必要はありません。Angularが自動的に推論します(github.com/angular/angular/blob/4.4.4/packages/http/src/…を参照)
Eran Medan

こんにちは !ヘッダーでポストサービスを渡したい場合-> 'application / json'のようなコンテンツタイプボディで渡す必要があるもの.... jsonオブジェクトを渡そうとしていますが、正しく機能していません...
VjyV

107

Angualar 4.3以降のアップデート

今ではHttpClient代わりに使用できますHttp

ガイドはこちら

サンプルコード

const myheader = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')
let body = new HttpParams();
body = body.set('username', USERNAME);
body = body.set('password', PASSWORD);
http
  .post('/api', body, {
    headers: myheader),
  })
  .subscribe();

非推奨

または、次のようにすることもできます。

let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', username);
urlSearchParams.append('password', password);
let body = urlSearchParams.toString()

2017年10月更新

よりangular4 +、我々は必要としないheaders、または.toString()詰め込みます。代わりに、以下の例のようにすることができます

import { URLSearchParams } from '@angular/http';

POST / PUTメソッド

let urlSearchParams = new URLSearchParams();
urlSearchParams.append('username', username);
urlSearchParams.append('password', password);
this.http.post('/api', urlSearchParams).subscribe(
      data => {
        alert('ok');
      },
      error => {
        console.log(JSON.stringify(error.json()));
      }
    )

GET / DELETEメソッド

    let urlSearchParams = new URLSearchParams();
    urlSearchParams.append('username', username);
    urlSearchParams.append('password', password);
    this.http.get('/api', { search: urlSearchParams }).subscribe(
      data => {
        alert('ok');
      },
      error => {
        console.log(JSON.stringify(error.json()));
      }
    )

JSON application/jsonContent-Typeの場合

this.http.post('/api',
      JSON.stringify({
        username: username,
        password: password,
      })).subscribe(
      data => {
        alert('ok');
      },
      error => {
        console.log(JSON.stringify(error.json()));
      }
      )

14
URLSearchParamsクラスをインポートすることを忘れないでくださいimport { URLSearchParams } from "angular2/http"
Sebastian Hernandez

10
私のインポートは違って見えます:import {URLSearchParams} from '@ angular / http';
2016年

しかし、フォームオブジェクトを送信するより簡単な方法はありませんか?URLSearchParams()を使用してRESTfulなバックエンドの投稿を送信するチュートリアルはありませんでした。彼らはどうやって?return this.http.post(this.actionUrl、body、{headers:this.headers}).map((response:Response)=> response.json()).catch(this.handleError);
stackdave 16

これはブール値でどのように機能しますか?ブール値または数値、文字列(追加)のみを追加できないというエラーが表示される
JohnAndrews

booleanについては、このトピックが役に立つかもしれません。stackoverflow.com/ questions / 14774907
Frank Nguyen

41

Angular2の新しいバージョンでContent-Typeは、適切なタイプのオブジェクトをとして渡す場合、ヘッダーを手動で設定し、本文をエンコードする必要はありませんbody

あなたは単にこれを行うことができます

import { URLSearchParams } from "@angular/http"


testRequest() {
  let data = new URLSearchParams();
  data.append('username', username);
  data.append('password', password);

  this.http
    .post('/api', data)
      .subscribe(data => {
            alert('ok');
      }, error => {
          console.log(error.json());
      });
}

このように、angularは本体をエンコードし、正しいContent-Typeヘッダーを設定します。

PSからインポートURLSearchParamsする@angular/httpことを忘れないでください、またはそれは動作しません。


2
@VStoykov動作しません。パラメータで.toString()を実行し、コンテンツタイプを指定する必要があります。角度を使用します4.0.3
Konrad

1
@ i'myourhuckleberry 4.0.3でも動作するはずです。ソースコードgithub.com/angular/angular/blob/4.0.3/packages/http/src/…を
VStoykov

1
@VStoykovそれは私にとってはうまくいきません、そして私はそれをGithubのバグとして報告しました
Konrad

1
OK。Nvm私はこれを "@ angular / http"からインポートする必要がありました。それ以外の場合はタイプを認識しますが、角度のタイプではありません。
Konrad

1
@ i'myourhuckleberryインポートは私の例の最初の行でしたが、おそらくそれを逃しました。ブラウザの組み込みタイプから、を使用できFormData、angularはどちらが機能するかを設定Content-Typemultipart/form-dataます。
VStoykov

10

だからそれを完全な答えにするために:

login(username, password) {
        var headers = new Headers();
        headers.append('Content-Type', 'application/x-www-form-urlencoded');
        let urlSearchParams = new URLSearchParams();
        urlSearchParams.append('username', username);
        urlSearchParams.append('password', password);
        let body = urlSearchParams.toString()
        return this.http.post('http://localHost:3000/users/login', body, {headers:headers})
            .map((response: Response) => {
                // login successful if there's a jwt token in the response
                console.log(response);
                var body = response.json();
                console.log(body);
                if (body.response){
                    let user = response.json();
                    if (user && user.token) {
                        // store user details and jwt token in local storage to keep user logged in between page refreshes
                        localStorage.setItem('currentUser', JSON.stringify(user)); 
                    }
                }
                else{
                    return body;
                }
            });
    }

1
[ts]タイプ '{ヘッダ​​ーの引数:RequestOptions; } 'はタイプ' RequestOptionsArgs 'のパラメーターに割り当てられません
Sonic Soul

2
@Sonic Soulそれだけです:.. post( '/ api'、body、headers)...ヘッダーの周りに{}なし
Guenther

5

これらの回答はすべて、HttpではなくHttpClientを利用している人には古くなっています。「URLSearchParamsのインポートは完了しましたが、.toString()と明示的なヘッダーなしではまだ機能しません!」

HttpClientでは、URLSearchParamsの代わりにHttpParamsを使用body = body.append()し、不変オブジェクトを使用しているため、構文を本文で複数のパラメーターに設定することに注意してください。

login(userName: string, password: string): Promise<boolean> {
    if (!userName || !password) {
      return Promise.resolve(false);
    }

    let body: HttpParams = new HttpParams();
    body = body.append('grant_type', 'password');
    body = body.append('username', userName);
    body = body.append('password', password);

    return this.http.post(this.url, body)
      .map(res => {
        if (res) {          
          return true;
        }
        return false;
      })
      .toPromise();
  }

上記の解決策をありがとう。しかし、ng build --prodを実行すると、私の本体のパラメーターは "{" params ":{" rawParams ":" "、" queryEncoder ":{}、" paramsMap ":{}}}:"のようになります。回避策はありますか?
Hemanth Poluru

4

角度バージョン4+(私のバージョンは4.3.6)で苦労している人がいます。これは私のために働いたサンプルコードでした。

最初に必要なインポートを追加します

import { Http, Headers, Response, URLSearchParams } from '@angular/http';

次に、api関数の場合。これは、必要に応じて変更できるログインサンプルです。

login(username: string, password: string) {
    var headers = new Headers();
    headers.append('Content-Type', 'application/x-www-form-urlencoded');
    let urlSearchParams = new URLSearchParams();
    urlSearchParams.append('email', username);
    urlSearchParams.append('password', password);
    let body = urlSearchParams.toString()

    return this.http.post('http://localhost:3000/api/v1/login', body, {headers: headers})
        .map((response: Response) => {
            // login successful if user.status = success in the response
            let user = response.json();
            console.log(user.status)
            if (user && "success" == user.status) {
                // store user details and jwt token in local storage to keep user logged in between page refreshes
                localStorage.setItem('currentUser', JSON.stringify(user.data));
            }
        });
}

0

複数のパラメーターを使用するすべてのアプローチで問題がありましたが、単一のオブジェクトで非常にうまく機能します

api:

    [HttpPut]
    [Route("addfeeratevalue")]
    public object AddFeeRateValue(MyValeObject val)

角度:

var o = {ID:rateId, AMOUNT_TO: amountTo, VALUE: value};
return this.http.put('/api/ctrl/mymethod', JSON.stringify(o), this.getPutHeaders());


private getPutHeaders(){
    let headers = new Headers();
    headers.append('Content-Type', 'application/json');
    return new RequestOptions({
        headers: headers
        , withCredentials: true // optional when using windows auth
    });
}

1
OPの問題は、application / x-www-form-urlencodedのコンテンツタイプです。あなたの答えはまったく別の問題です。
Christian Ulbrich 2017

0
angular: 
    MethodName(stringValue: any): Observable<any> {
    let params = new HttpParams();
    params = params.append('categoryName', stringValue);

    return this.http.post('yoururl', '', {
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      params: params,
      responseType: "json"
    })
  }

api:   
  [HttpPost("[action]")]
  public object Method(string categoryName)

こんにちは、Stackoverflowへようこそ。この質問に回答していただきありがとうございます。コードブロックを投稿するだけでは、OPや将来この質問に遭遇した人にとって理解が困難です。ソリューションをよりよく理解するために、質問を編集して、解決した問題とその解決方法について(簡単な)説明を提供できますか?
Plutian

1
こんにちは@Plutianポストリクエストの2番目のパラメーターに値を渡すと、APIにnull値が返されたので、2番目のパラメーターを空の文字列として渡し、3番目のパラメーターのparamsプロパティに値を渡したので、このメソッドは私のために機能しました
Muniyan

-2

私が同様のことをしようとしたときに私はここに着陸しました。application / x-www-form-urlencodedコンテンツタイプの場合、これを本文に使用することができます。

var body = 'username' =myusername & 'password'=mypassword;

bodyに割り当てられた値を実行してみた結果は文字列になります。


Joshuaが指摘したように、これは有効なJavaScriptでもTypeScriptでもありません。あなたが言ったことはまさに現在受け入れられている答えだと思います。
Christian Ulbrich 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.