Angular2 - Tham số yêu cầu Http POST


91

Tôi đang cố gắng thực hiện một yêu cầu ĐĂNG nhưng tôi không thể làm cho nó hoạt động:

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

Về cơ bản tôi muốn sao chép yêu cầu http này (không phải ajax) giống như nó được bắt nguồn bởi một biểu mẫu html:

URL: / api

Tham số: tên người dùng và mật khẩu


hãy xem stackoverflow.com/a/34758630/5043867stackoverflow.com/a/34823818/5043867 này sẽ giải thích sâu hơn về yêu cầu POST!
Pardeep Jain

@PardeepJain Tôi không cố sử dụng API. Chỉ để mô phỏng một BÀI ĐĂNG được tạo bởi một dạng html.
Christopher

cũng kiểm tra ở đây, đăng tệp với user_namepassword, stackoverflow.com/a/45879409/2803344
Belter

Câu trả lời:


49

Tôi nghĩ rằng application/x-www-form-urlencodednội dung không chính xác cho một loại nội dung. Bạn có thể thử sử dụng cái này:

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

Hy vọng nó sẽ giúp bạn, Thierry


vâng với kiểu nội dung trong tiêu đề, đó là giải pháp duy nhất đi qua giá trị trong "theo cách cũ" thay vì chuỗi json
Nather Webber

Đây không phải là một câu trả lời hay. Thay vào đó, hãy sử dụng URLSearchParams, như được đề cập bên dưới với nhiều lượt ủng hộ hơn.
Mick

Đối với những người đến từ tương lai đến từ tìm kiếm trên Google, đây không phải là câu trả lời tốt nhất (không xúc phạm Thierry! Câu trả lời của bạn vẫn đúng về mặt kỹ thuật :)). Câu trả lời của V Stoykov cho đến nay là chính xác nhất. ps đảm bảo import { URLSearchParams } from "@angular/http"và không phải là mặc định, vì vậy 1) bạn không cần phải làm .toStringtrên nó, và 2) bạn không cần đặt loại nội dung. Góc sẽ suy ra nó tự động cho bạn (xem github.com/angular/angular/blob/4.4.4/packages/http/src/... )
Eran Medan

Chào ! nếu tôi muốn chuyển dịch vụ đăng bài với tiêu đề -> loại nội dung như 'ứng dụng / json' thì tôi cần chuyển những gì trong nội dung .... tôi đang cố chuyển đối tượng json nhưng nó không hoạt động bình thường ...
VjyV

107

Cập nhật cho Angualar 4.3+

Bây giờ chúng ta có thể sử dụng HttpClientthay vìHttp

Hướng dẫn ở đây

Mã mẫu

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

Không được chấp nhận

Hoặc bạn có thể làm như sau:

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

Cập nhật tháng 10/2017

Từ angle4 + , chúng tôi không cần headers, hoặc .toString()chất liệu. Thay vào đó, bạn có thể làm như ví dụ dưới đây

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

Phương thức 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()));
      }
    )

Phương thức 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()));
      }
    )

Đối với loại application/jsonnội dung JSON

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

14
Đừng quên nhập Lớp URLSearchParamsimport { URLSearchParams } from "angular2/http"
Sebastian Hernandez

10
quá trình nhập của tôi trông khác: nhập {URLSearchParams} từ '@ angle / http';
dang

nhưng, không có cách nào đơn giản hơn để gửi một đối tượng biểu mẫu? Tôi không thấy bất kỳ hướng dẫn nào sử dụng URLSearchParams () để gửi bài đăng cho một chương trình phụ trợ với phần còn lại. họ làm như thế nào? return this.http.post (this.actionUrl, body, {headers: this.headers}) .map ((response: Response) => response.json ()) .catch (this.handleError);
stackdave

Điều này hoạt động như thế nào với boolean?
Gặp

Về boolean, có lẽ chủ đề này có thể giúp bạn stackoverflow.com/questions/14774907/…
Frank Nguyen

41

Trong các phiên bản sau của Angular2, không cần thiết lập thủ công Content-Typetiêu đề và mã hóa phần nội dung nếu bạn chuyển một đối tượng đúng loại như body.

Bạn chỉ có thể làm điều này

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

Bằng cách này, góc sẽ mã hóa phần nội dung cho bạn và sẽ đặt Content-Typetiêu đề chính xác .

PS Đừng quên nhập URLSearchParamstừ @angular/httpnếu không nó sẽ không hoạt động.


2
@VStoykov nó không hoạt động, bạn phải .toString () trên tham số và bạn phải chỉ định loại nội dung và tôi sử dụng góc 4.0.3
Konrad

1
@ i'myourhuckleberry Nó sẽ hoạt động ngay cả trên 4.0.3. Nhìn vào mã nguồn github.com/angular/angular/blob/4.0.3/packages/http/src/…
VStoykov

1
@VStoykov nó không hoạt động với tôi và tôi đã báo cáo nó là một lỗi trên Github
Konrad

1
ĐỒNG Ý. Nvm Tôi đã phải nhập cái này từ "@ angle / http" nếu không nó nhận dạng được kiểu nhưng không phải kiểu của góc.
Konrad

1
@ i'myourhuckleberry nhập là dòng đầu tiên trong ví dụ của tôi, nhưng có lẽ bạn đã bỏ qua. Từ các kiểu tích hợp sẵn trong trình duyệt, bạn có thể sử dụng FormDatavà góc sẽ được đặt Content-Typenhư kiểu multipart/form-datacũng hoạt động.
VStoykov

10

vì vậy chỉ để biến nó thành một câu trả lời hoàn chỉnh:

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] Đối số kiểu '{headers: RequestOptions; } 'không thể gán cho tham số kiểu' RequestOptionsArgs '
Sonic Soul

2
@Sonic Soul nó chỉ là: .. post ('/ api', body, headers) ... mà không có {} xung quanh tiêu đề
Guenther

5

Những câu trả lời này đều đã lỗi thời đối với những người sử dụng HttpClient hơn là Http. Tôi bắt đầu phát điên khi nghĩ rằng, "Tôi đã thực hiện nhập URLSearchParams nhưng nó vẫn không hoạt động nếu không có .toString () và tiêu đề rõ ràng!"

Với HttpClient, hãy sử dụng HttpParams thay vì URLSearchParams và lưu ý body = body.append()cú pháp để đạt được nhiều tham số trong phần thân vì chúng tôi đang làm việc với một đối tượng không thể thay đổi:

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

cảm ơn cho giải pháp trên. Nhưng khi chạy ng build --prod body param's của tôi trông giống như "{" params ": {" rawParams ":" "," queryEncoder ": {}," paramsMap ": {}}}:". Có bất kỳ công việc xung quanh.
Hemanth Poluru

4

Nếu ai đang gặp khó khăn với phiên bản 4+ góc cạnh (của tôi là 4.3.6) . Đây là mã mẫu phù hợp với tôi.

Đầu tiên hãy thêm các mục nhập bắt buộc

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

Sau đó cho hàm api. Đó là một mẫu đăng nhập có thể được thay đổi theo nhu cầu của bạn.

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

Tôi gặp vấn đề với mọi cách tiếp cận sử dụng nhiều tham số, nhưng nó hoạt động khá tốt với một đối tượng

api:

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

góc cạnh:

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
Vấn đề của OP là loại nội dung của ứng dụng / x-www-form-urlencoded, câu trả lời của bạn là một vấn đề hoàn toàn khác.
Christian Ulbrich

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)

Xin chào và chào mừng bạn đến với Stackoverflow. Cảm ơn bạn đã trả lời câu hỏi này, nhưng chỉ đăng một khối mã sẽ khó hiểu đối với OP hoặc bất kỳ ai gặp câu hỏi này trong tương lai. Bạn có thể chỉnh sửa câu hỏi của mình và đưa ra lời giải thích (ngắn gọn) về vấn đề bạn đã giải quyết và cách bạn giải quyết nó, để giúp chúng tôi hiểu giải pháp của bạn hơn không?
Plutian

1
Xin chào @Plutian khi tôi truyền giá trị vào tham số thứ 2 của yêu cầu bài đăng, nó trả về cho tôi các giá trị null trên api vì vậy tôi đã chuyển tham số thứ 2 đó dưới dạng chuỗi trống và tôi đã chuyển các giá trị trên thuộc tính params của tham số thứ 3 nên phương thức này phù hợp với tôi
Muniyan

-2

Tôi đã hạ cánh ở đây khi tôi đang cố gắng làm một điều tương tự. Đối với loại nội dung application / x-www-form-urlencoded, bạn có thể thử sử dụng loại nội dung này cho phần nội dung:

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

với những gì bạn đã thử thực hiện, giá trị được gán cho body sẽ là một chuỗi.


Như Joshua đã chỉ ra, đây không phải là JavaScript cũng như TypeScript hợp lệ. Tôi nghĩ ý của bạn chính xác là câu trả lời được chấp nhận.
Christian Ulbrich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.