Angular2 - Parameter permintaan Http POST

94

Saya mencoba membuat permintaan POST tetapi saya tidak bisa membuatnya berfungsi:

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

Saya pada dasarnya ingin mereplikasi permintaan http ini (bukan ajax) seperti yang berasal dari bentuk html:

URL: / api

Params: username dan password

Christopher
sumber
lihat stackoverflow.com/a/34758630/5043867 dan stackoverflow.com/a/34823818/5043867 ini, ini akan menjelaskan semua tentang permintaan POST secara mendalam!
Pardeep Jain
@PardeepJain Saya tidak mencoba menggunakan API. Hanya untuk mensimulasikan POST yang berasal dari bentuk html.
Christopher
juga periksa di sini, kirim file dengan user_namedan password, stackoverflow.com/a/45879409/2803344
Belter

Jawaban:

49

Saya pikir body tidak benar untuk application/x-www-form-urlencodedtipe konten. Anda dapat mencoba menggunakan ini:

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

Semoga bisa membantu Anda, Thierry

Thierry Templier
sumber
ya dengan jenis konten itu di tajuk, itu adalah satu-satunya solusi yang meneruskan nilai dalam "cara lama" alih-alih string json
Nather Webber
Ini bukan jawaban yang bagus. Gunakan URLSearchParams sebagai gantinya, seperti yang disebutkan di bawah ini dengan lebih banyak suara positif.
Mick
Untuk orang-orang dari masa depan yang datang dari pencarian Google, ini bukan jawaban terbaik (jangan tersinggung Thierry! Jawaban Anda masih benar secara teknis :)). V Stoykov ini jawabannya adalah sejauh yang paling akurat. ps pastikan untuk import { URLSearchParams } from "@angular/http"dan bukan yang default jadi 1) Anda tidak perlu melakukan .toStringdi atasnya, dan 2) Anda tidak perlu mengatur tipe konten. Angular akan menyimpulkannya secara otomatis untuk Anda (lihat github.com/angular/angular/blob/4.4.4/packages/http/src/… )
Eran Medan
Hai! jika saya ingin melewati layanan pos dengan header -> tipe konten seperti 'application / json' apa yang harus saya berikan di body .... saya mencoba untuk melewatkan objek json tetapi; tidak berfungsi dengan benar ...
VjyV
107

Pembaruan untuk Angualar 4.3+

Sekarang kita dapat menggunakan HttpClientbukannyaHttp

Panduan ada di sini

Kode sampel

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

Tidak digunakan lagi

Atau Anda bisa melakukan seperti ini:

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

Perbarui Oktober / 2017

Dari angular4 + , kami tidak membutuhkan headers, atau .toString()barang. Sebagai gantinya, Anda dapat melakukan seperti contoh di bawah ini

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

Metode 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 metode

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

Untuk application/jsonJenis Konten JSON

this.http.post('/api',
      JSON.stringify({
        username: username,
        password: password,
      })).subscribe(
      data => {
        alert('ok');
      },
      error => {
        console.log(JSON.stringify(error.json()));
      }
      )
Frank Nguyen
sumber
14
Jangan lupa untuk mengimpor Kelas URLSearchParamsimport { URLSearchParams } from "angular2/http"
Sebastian Hernandez
10
impor saya terlihat berbeda: impor {URLSearchParams} dari '@ angular / http';
dang
Tapi, ada cara yang lebih sederhana untuk mengirim objek formulir? saya tidak melihat tutorial apa pun menggunakan URLSearchParams () untuk mengirim posting untuk backend dengan tenang. bagaimana mereka melakukannya? kembalikan this.http.post (this.actionUrl, body, {headers: this.headers}) .map ((response: Response) => response.json ()) .catch (this.handleError);
stackdave
Bagaimana cara kerjanya dengan boolean? Mendapatkan kesalahan yang mengatakan bahwa saya tidak dapat menambahkan boolean atau angka, hanya string (dalam lampiran)
JohnAndrews
Tentang boolean, mungkin topik ini dapat membantu Anda stackoverflow.com/questions/14774907/…
Frank Nguyen
41

Di versi Angular2 yang lebih baru, tidak perlu mengatur Content-Typeheader dan pengkodean badan secara manual jika Anda meneruskan objek dengan jenis yang tepat sebagai body.

Anda bisa melakukan ini

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

Dengan cara ini sudut akan menyandikan tubuh untuk Anda dan akan mengatur Content-Typetajuk yang benar .

PS Jangan lupa untuk mengimpor URLSearchParamsdari @angular/httpatau tidak akan berhasil.

VStoykov
sumber
2
@VStoykov tidak berfungsi, Anda harus .toString () pada params dan Anda harus menentukan jenis konten, dan saya menggunakan angular 4.0.3
Konrad
1
@ i'myourhuckleberry Ini harus bekerja bahkan pada 4.0.3. Lihat kode sumber github.com/angular/angular/blob/4.0.3/packages/http/src/…
VStoykov
1
@VStoykov tidak bekerja untuk saya dan saya telah melaporkannya sebagai bug di Github
Konrad
1
BAIK. Nvm Saya harus mengimpor ini dari "@ angular / http" jika tidak ia mengenali tipe tapi itu bukan tipe sudut.
Konrad
1
@ i'myourhuckleberry impor adalah baris pertama dalam contoh saya, tetapi mungkin Anda melewatkannya. Dari jenis bawaan di browser yang dapat Anda gunakan FormData, dan sudut akan ditetapkan Content-Typesebagai multipart/form-datayang juga berfungsi.
VStoykov
10

jadi hanya untuk membuatnya menjadi jawaban lengkap:

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;
                }
            });
    }
dang
sumber
1
[ts] Argumen bertipe '{headers: RequestOptions; } 'tidak dapat ditetapkan ke parameter jenis' RequestOptionsArgs '
Sonic Soul
2
@Sonic Soul hanya saja: .. post ('/ api', body, headers) ... tanpa {} sekitar header
Guenther
5

Semua jawaban ini sudah ketinggalan zaman untuk mereka yang menggunakan HttpClient daripada Http. Saya mulai menjadi gila berpikir, "Saya telah melakukan impor URLSearchParams tetapi masih tidak berfungsi tanpa .toString () dan header eksplisit!"

Dengan HttpClient, gunakan HttpParams sebagai ganti URLSearchParams dan catat body = body.append()sintaksnya untuk mencapai beberapa params di dalam tubuh karena kita bekerja dengan objek yang tidak bisa diubah:

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();
  }
333Matt
sumber
terima kasih atas solusi di atas. Tetapi ketika menjalankan ng build --prod, parameter tubuh saya terlihat seperti "{" params ": {" rawParams ":" "," queryEncoder ": {}," paramsMap ": {}}}:". Apakah ada jalan keluar.
Hemanth Poluru
4

Jika ada yang berjuang dengan versi sudut 4+ (milik saya 4.3.6) . Ini adalah kode contoh yang berhasil untuk saya.

Pertama tambahkan impor yang diperlukan

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

Kemudian untuk fungsi api. Ini adalah contoh login yang dapat diubah sesuai kebutuhan Anda.

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));
            }
        });
}
Krishnadas PC
sumber
1
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)
Muniyan
sumber
Halo dan selamat datang di Stackoverflow. Terima kasih telah menjawab pertanyaan ini, tetapi mengeposkan blok kode saja sulit dipahami untuk OP atau siapa pun yang menemukan pertanyaan ini di masa mendatang. Apakah Anda dapat mengedit pertanyaan Anda dan memberikan penjelasan (singkat) tentang masalah apa yang telah Anda selesaikan, dan bagaimana Anda menyelesaikannya, untuk membantu kami memahami solusi Anda dengan lebih baik?
Plutian
1
Hai @Plutian ketika saya memberikan nilai pada parameter ke-2 dari permintaan posting itu mengembalikan saya nilai nol pada api jadi saya melewati parameter ke-2 itu sebagai string kosong dan saya meneruskan nilai pada properti params dari parameter ke-3 sehingga metode ini berfungsi untuk saya
Muniyan
0

Saya mengalami masalah dengan setiap pendekatan yang menggunakan beberapa parameter, tetapi berfungsi cukup baik dengan objek tunggal

api:

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

sudut:

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
    });
}
Sonic Soul
sumber
1
Masalah OP adalah jenis konten aplikasi / x-www-form-urlencoded, jawaban Anda adalah masalah yang sama sekali berbeda.
Christian Ulbrich
-2

Saya mendarat di sini ketika saya mencoba melakukan hal serupa. Untuk jenis konten application / x-www-form-urlencoded, Anda dapat mencoba menggunakan ini untuk body:

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

dengan apa yang Anda coba lakukan, nilai yang ditetapkan ke body akan menjadi string.

adongo
sumber
Seperti yang ditunjukkan Joshua, ini bukan JavaScript atau TypeScript yang valid. Saya pikir apa yang Anda maksud adalah jawaban yang diterima saat ini.
Christian Ulbrich