Angular2 - Http POST istek parametreleri


94

POST isteğinde bulunmaya çalışıyorum ama çalıştıramıyorum:

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

Temel olarak bu http isteğini (ajax değil) bir html formu tarafından oluşturulmuş gibi çoğaltmak istiyorum:

URL: / api

Parametreler: kullanıcı adı ve şifre


bu stackoverflow.com/a/34758630/5043867 ve stackoverflow.com/a/34823818/5043867'ye bir göz atın, bu POST isteğiyle ilgili her şeyi derinlemesine açıklayacaktır!
Pardeep Jain

@PardeepJain bir API tüketmeye çalışmıyorum. Sadece bir html formundan kaynaklanan bir POST'u simüle etmek için.
Christopher

Ayrıca, burada kontrol içeren bir dosyayı gönderebilir user_nameve password, stackoverflow.com/a/45879409/2803344
Belter

Yanıtlar:


49

Vücudun bir application/x-www-form-urlencodediçerik türü için doğru olmadığını düşünüyorum . Bunu kullanmayı deneyebilirsiniz:

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

Umarım sana yardımcı olur, Thierry


evet, başlıktaki bu içerik türü ile, değerleri json dizesi yerine "eski şekilde" geçiren tek çözüm budur
Nather Webber

Bu iyi bir cevap değil. Bunun yerine, aşağıda belirtildiği gibi daha fazla olumlu oyla URLSearchParams kullanın.
Mick

Gelecekten bir Google aramasından gelecek kişiler için bu en iyi cevap değil (alınmayın Thierry! Cevabınız teknik olarak hala doğru :)). V Stoykov'un cevabı şu ana kadar en doğru olanıdır. ps import { URLSearchParams } from "@angular/http"varsayılan olanı değil, bu nedenle 1) üzerinde yapmanız gerekmediğinden .toStringve 2) içerik türünü ayarlamanıza gerek olmadığından emin olun. Angular bunu sizin için otomatik olarak çıkaracaktır (bkz. Github.com/angular/angular/blob/4.4.4/packages/http/src/… )
Eran Medan

Selam ! post servisini başlık ile iletmek istersem -> 'application / json' gibi içerik türü vücutta
iletmem gerekenler

107

Angualar 4.3+ güncellemesi

Şimdi HttpClientyerine kullanabilirizHttp

Rehber burada

Basit kod

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

Kullanımdan kaldırıldı

Veya bunun gibi yapabilirsiniz:

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

Güncelleme Ekim / 2017

Gönderen angular4 + , ihtiyacımız yok headers, ya da .toString()maddeler. Bunun yerine, aşağıdaki örnekte olduğu gibi yapabilirsiniz

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

POST / PUT yöntemi

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 yöntemi

    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 için

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

14
URLSearchParams Sınıfını içe aktarmayı unutmayınimport { URLSearchParams } from "angular2/http"
Sebastian Hernandez

10
içe aktarmam farklı görünüyor: {URLSearchParams} öğesini '@ angular / http'den içe aktarın;
dang

ancak, bir form nesnesi göndermenin daha basit bir yolu yok mu? Huzurlu bir arka uç için gönderi göndermek için URLSearchParams () kullanarak herhangi bir eğitim görmedim. nasıl yaparlar? this.http.post (this.actionUrl, body, {headers: this.headers}) .map ((response: Response) => response.json ()) .catch (this.handleError);
stackdave

Bu boolelerle nasıl çalışır?
Boole

Boole hakkında, belki bu konu size stackoverflow.com/questions/14774907/…
Frank Nguyen

41

Angular2'nin sonraki sürümlerinde Content-Type, doğru türde bir nesneyi olarak iletirseniz, başlığı manuel olarak ayarlamanıza ve gövdeyi kodlamanıza gerek yoktur body.

Bunu basitçe yapabilirsin

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

Bu şekilde açısal, bedeni sizin için kodlayacak ve doğru Content-Typebaşlığı ayarlayacaktır .

PS Do içe unutmayın URLSearchParamsgelen @angular/httpveya işe yaramaz.


2
@VStoykov işe yaramıyor, params üzerinde .toString () yapmanız gerekiyor ve içerik türünü belirtmeniz gerekiyor ve ben açısal 4.0.3
Konrad

1
@ i'myourhuckleberry 4.0.3'te bile çalışmalı. Kaynak koduna bakın: github.com/angular/angular/blob/4.0.3/packages/http/src/…
VStoykov

1
@VStoykov benim için çalışmıyor ve bunu Github'da bir hata olarak bildirdim
Konrad

1
TAMAM. Nvm Bunu "@ angular / http" den içe aktarmak zorunda kaldım, aksi takdirde türü tanıyor, ancak açısal türü değil.
Konrad

1
@ i'myourhuckleberry, örneğimdeki ilk satır içe aktarımdı, ancak muhtemelen kaçırdınız. Tarayıcıda türleri yerleşik itibaren kullanabileceğiniz FormDatave açısal ayarlar Content-Typeolarak multipart/form-datada çalışmalarını.
VStoykov

10

tam bir cevap yapmak için:

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] '{headers: RequestOptions; } ',' RequestOptionsArgs 'türündeki bir parametreye atanamaz
Sonic Soul

2
@Sonic Soul is just: .. post ('/ api', body, headers) ... başlıkların etrafında {} olmadan
Guenther

5

Bu yanıtların tümü, Http yerine HttpClient kullananlar için geçerliliğini yitirmiştir. "URLSearchParams'ın içe aktarımını yaptım ama yine de .toString () ve açık başlık olmadan çalışmıyor!" Diye düşünmeye başlıyordum.

HttpClient ile URLSearchParams yerine HttpParams kullanın ve body = body.append()değişmez bir nesneyle çalıştığımız için vücutta birden çok parametre elde etmek için sözdizimini not edin :

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

Yukarıdaki çözüm için teşekkürler. Ancak ng build --prod çalıştırırken vücut parametrelerim "{" params ": {" rawParams ":" "," queryEncoder ": {}," paramsMap ": {}}}:" gibi görünüyor. Etrafta herhangi bir iş var mı?
Hemanth Poluru

4

Açısal sürüm 4+ ile mücadele eden biri varsa (benimki 4.3.6 idi) . Bu benim için çalışan örnek koddu.

Önce gerekli içe aktarmaları ekleyin

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

Daha sonra api işlevi için. İhtiyaçlarınıza göre değiştirilebilen bir giriş örneğidir.

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

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)

Merhaba ve Stackoverflow'a hoş geldiniz. Bu soruyu yanıtladığınız için teşekkür ederiz, ancak sadece bir kod bloğu göndermek, OP veya gelecekte bu soruyla karşılaşacak herkes için anlaşılması zor. Eğer mümkün olacaktır düzenlemek soru ve sorun çözüldü ne olduğu bir (kısa) açıklama ve bunu nasıl çözdüğünü, bize daha iyi bir çözüm anlamalarına yardımcı olmak?
Plutian

1
Merhaba @Plutian, post isteğinin 2. parametresindeki değeri ilettiğimde bana api üzerindeki boş değerleri döndürüyor, böylece 2. parametreyi boş dize olarak geçtim ve 3. parametrenin params özelliğindeki değerleri geçtim, bu yüzden bu yöntem benim için çalıştı
Muniyan

0

Birden çok parametre kullanan her yaklaşımda sorun yaşıyordum, ancak tek nesne ile oldukça iyi çalışıyor

api:

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

açısal:

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'nin problemi içerik-tipi uygulama / x-www-form-urlencoded, cevabınız tamamen farklı bir problem.
Christian Ulbrich

-2

Ben de benzer bir şey yapmaya çalışırken buraya indim. Bir uygulama / x-www-form-urlencoded içerik türü için, bunu gövde için kullanmayı deneyebilirsiniz:

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

Yapmaya çalıştığınız şey gövdeye atanan değer bir dizge olacaktır.


Joshua'nın işaret ettiği gibi, bu geçerli bir JavaScript veya TypeScript değildir. Sanırım kastettiğin tam olarak şu anda kabul edilen cevap.
Christian Ulbrich
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.