Thêm một tiêu đề HTTP vào Angular HttpClient không gửi tiêu đề, tại sao?


180

Đây là mã của tôi:

import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';

logIn(username: string, password: string) {
    const url = 'http://server.com/index.php';
    const body = JSON.stringify({username: username,
                                 password: password});
    const headers = new HttpHeaders();
    headers.set('Content-Type', 'application/json; charset=utf-8');
    this.http.post(url, body, {headers: headers}).subscribe(
        (data) => {
            console.log(data);
        },
        (err: HttpErrorResponse) => {
            if (err.error instanceof Error) {
                console.log('Client-side error occured.');
            } else {
                console.log('Server-side error occured.');
            }
        }
    );
}

và ở đây gỡ lỗi mạng:

Request Method:POST
Status Code:200 OK
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:no-cache
Connection:keep-alive
Content-Length:46
Content-Type:text/plain

và Dữ liệu được lưu trữ trong 'Yêu cầu tải trọng' nhưng trong máy chủ của tôi không nhận được các giá trị POST:

print_r($_POST);
Array
(
)

Tôi tin rằng lỗi xuất phát từ tiêu đề không được đặt trong POST, tôi đã làm gì sai?


Vâng cảm ơn! Nhưng sau khi không nhận được dữ liệu trên Back-end của mình, tôi đã truy cập application / x-www-form-urlencoding. Dù sao, câu hỏi chính là anserwerd
Frennetix

Kiểm tra ví dụ HTTPClient Angular 8 này để sử dụng API RESTFul với tiêu đề tùy chỉnh và Xử lý lỗi freakyjolly.com/
Spy Spy

Câu trả lời:


309

Các thể hiện của HttpHeaderlớp mới là các đối tượng bất biến . Gọi các phương thức lớp sẽ trả về một thể hiện mới. Về cơ bản, bạn cần làm như sau:

let headers = new HttpHeaders();
headers = headers.set('Content-Type', 'application/json; charset=utf-8');

hoặc là

const headers = new HttpHeaders({'Content-Type':'application/json; charset=utf-8'});

Cập nhật: thêm nhiều tiêu đề

let headers = new HttpHeaders();
headers = headers.set('h1', 'v1').set('h2','v2');

hoặc là

const headers = new HttpHeaders({'h1':'v1','h2':'v2'});

Cập nhật: chấp nhận bản đồ đối tượng cho các tiêu đề & params của httpClient

5.0.0-beta.6 hiện có thể bỏ qua việc tạo HttpHeadersđối tượng, trực tiếp truyền bản đồ đối tượng làm đối số. Vì vậy, bây giờ có thể làm như sau:

http.get('someurl',{
   headers: {'header1':'value1','header2':'value2'}
});

50
Hấp dẫn. Vì vậy, đối với chúng tôi đến từ thế giới OO, settên phương thức có phần sai lệch.
tishma

3
Nếu tôi muốn đặt nhiều tiêu đề thì sao? Tôi đã cố gắng xâu chuỗi nhận xét HttpHeaders().set(..).set(..)nhưng bây giờ một lần nữa các tiêu đề không được ghi vào các trường tiêu đề HTTP?!
hiển thị

Nó sẽ hoạt động tốt theo src github.com/angular/angular/blob/master/packages/common/http/src/ . Tôi không thể giúp bạn thêm nữa mà không có thêm thông tin về vấn đề của bạn (mã)
Jota.Toledo

Vì vậy, trong trường hợp của tôi, tôi đã phạm sai lầm bằng cách chuyển các tiêu đề & params trong danh sách các đối số thành một hàm (vì cả hai đều chấp nhận một đối tượng json). Có nghĩa là chỉ cần coi chừng các lỗi và httpHeaders là loại là một cách thực hành tốt .. Ngoài chủ đề: khi bạn có thể sử dụng các đối tượng ở mọi nơi, đừng sử dụng TypeScript nhưng VanillaJS.
nguy hiểm89

3
Tại sao các tiêu đề và yêu cầu được thực hiện bất biến? angular.io/guide/http#immutability
Drellgor

23

Để thêm nhiều thông số hoặc tiêu đề, bạn có thể làm như sau:

constructor(private _http: HttpClient) {}

//....

const url = `${environment.APP_API}/api/request`;

let headers = new HttpHeaders().set('header1', hvalue1); // create header object
headers = headers.append('header2', hvalue2); // add a new header, creating a new object
headers = headers.append('header3', hvalue3); // add another header

let params = new HttpParams().set('param1', value1); // create params object
params = params.append('param2', value2); // add a new param, creating a new object
params = params.append('param3', value3); // add another param 

return this._http.get<any[]>(url, { headers: headers, params: params })

1
Phương pháp này dường như cũng không hoạt động. Ý tôi là, bạn có thể thêm các tiêu đề và chúng sẽ hiển thị trong thuộc lazyUpdatetính, nhưng cuối cùng nó sẽ bị lỗi CreateListFromArrayLikengoại lệ khi thực hiện yêu cầu có hiệu lực bằng cách đăng ký vào nó.
Jago

3
Để thêm nhiều tiêu đề, hãy sử dụng: tiêu đề: HttpHeaders = new HttpHeaders ({'Application-Id': this.appId, "REST-API-Key": this.apiKey, "Content-Type": "application / json"});
Benson

13

đặt tiêu đề http như bên dưới trong yêu cầu http của bạn

return this.http.get(url, { headers: new HttpHeaders({'Authorization': 'Bearer ' + token})
 });

5

Tôi đã vật lộn với điều này trong một thời gian dài. Tôi đang sử dụng Angular 6 và tôi thấy rằng

let headers = new HttpHeaders();
headers = headers.append('key', 'value');

đã không làm việc. Nhưng những gì đã làm việc là

let headers = new HttpHeaders().append('key', 'value');

đã làm, điều đó có ý nghĩa khi bạn nhận ra họ là bất biến. Vì vậy, khi tạo một tiêu đề bạn không thể thêm vào nó. Tôi đã không thử nó, nhưng tôi nghi ngờ

let headers = new HttpHeaders();
let headers1 = headers.append('key', 'value');

cũng sẽ làm việc


Lần thử đầu tiên của bạn sẽ hoạt động, bạn đang gán kết quả của phần bổ sung cho biến tiêu đề. Ngay bây giờ lời giải thích của bạn không có ý nghĩa gì, đặc biệt là dự đoán cuối cùng của bạn rằng việc thêm một let có thể khắc phục nó
Juan Mendes

3

Tôi đã ở với Angular 8 và điều duy nhất phù hợp với tôi là:

  getCustomHeaders(): HttpHeaders {
    const headers = new HttpHeaders()
      .set('Content-Type', 'application/json')
      .set('Api-Key', 'xxx');
    return headers;
  }

2

Trong hướng dẫn sử dụng ( https://angular.io/guide/http ) tôi đọc: Lớp HttpHeaders là bất biến, vì vậy mọi tập hợp () trả về một thể hiện mới và áp dụng các thay đổi.

Đoạn mã sau hoạt động với tôi với angular-4:

 return this.http.get (url, {headers: new httpHeaders (). set ('UserEmail', email)});

0

Trong ứng dụng kế thừa của tôi Array.from của nguyên mẫu js đã xung đột với Array.from của angular đã gây ra vấn đề này. Tôi đã giải quyết nó bằng cách lưu phiên bản Array.from của angular và gán lại sau khi tải nguyên mẫu.


-3

Ví dụ về Dịch vụ httpClient 8 góc với Xử lý lỗiTiêu đề tùy chỉnh

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
    import { Student } from '../model/student';
    import { Observable, throwError } from 'rxjs';
    import { retry, catchError } from 'rxjs/operators';

    @Injectable({
      providedIn: 'root'
    })
    export class ApiService {

      // API path
      base_path = 'http://localhost:3000/students';

      constructor(private http: HttpClient) { }

      // Http Options
      httpOptions = {
        headers: new HttpHeaders({
          'Content-Type': 'application/json'
        })
      }

      // Handle API errors
      handleError(error: HttpErrorResponse) {
        if (error.error instanceof ErrorEvent) {
          // A client-side or network error occurred. Handle it accordingly.
          console.error('An error occurred:', error.error.message);
        } else {
          // The backend returned an unsuccessful response code.
          // The response body may contain clues as to what went wrong,
          console.error(
            `Backend returned code ${error.status}, ` +
            `body was: ${error.error}`);
        }
        // return an observable with a user-facing error message
        return throwError(
          'Something bad happened; please try again later.');
      };


      // Create a new item
      createItem(item): Observable<Student> {
        return this.http
          .post<Student>(this.base_path, JSON.stringify(item), this.httpOptions)
          .pipe(
            retry(2),
            catchError(this.handleError)
          )
      }

      ....
      ....

nhập mô tả hình ảnh ở đây

Kiểm tra hướng dẫn ví dụ đầy đủ ở đây


3
Là tôi hay đây là quá mức cần thiết cho câu hỏi được hỏi?
Ojonugwa Jude Ochalifu

3
Đây không phải là cố gắng trả lời câu hỏi OP. Nó chỉ là một loạt các mã mà không có lời giải thích nào.
Jota.Toledo
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.