การเพิ่มส่วนหัว HTTP ไปยัง Angular HttpClient ไม่ส่งส่วนหัวทำไม?


181

นี่คือรหัสของฉัน:

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

และนี่คือการแก้ปัญหาเครือข่าย:

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

และข้อมูลถูกเก็บไว้ใน 'คำขอโหลด' แต่ในเซิร์ฟเวอร์ของฉันไม่ได้รับค่า POST:

print_r($_POST);
Array
(
)

ฉันเชื่อว่าข้อผิดพลาดมาจากส่วนหัวที่ไม่ได้ตั้งค่าในระหว่าง POST ฉันทำอะไรผิด


ใช่ขอบคุณ! แต่หลังจากไม่ได้รับข้อมูลบน Back-end ของฉันฉันไปที่ application / x-www-form-urlencoded อย่างไรก็ตามคำถามหลักคือ anserwerd
Frennetix

ลองดูตัวอย่าง HTTPClient เชิงมุม 8 นี้เพื่อใช้ RESTFul API พร้อมส่วนหัวที่กำหนดเองและการจัดการข้อผิดพลาดfreakyjolly.com/…
รหัส Spy

คำตอบ:


311

อินสแตนซ์ของHttpHeaderคลาสใหม่เป็นวัตถุที่ไม่เปลี่ยนรูป การเรียกเมธอดคลาสจะส่งคืนอินสแตนซ์ใหม่ตามผลลัพธ์ โดยพื้นฐานแล้วคุณต้องทำสิ่งต่อไปนี้:

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

หรือ

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

อัปเดต: เพิ่มหลายส่วนหัว

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

หรือ

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

อัปเดต: ยอมรับการแมปวัตถุสำหรับส่วนหัวและพารามิเตอร์ HttpClient

ตั้งแต่5.0.0-beta.6 ในขณะนี้สามารถข้ามการสร้างHttpHeadersวัตถุและส่งผ่านการแมปวัตถุเป็นอาร์กิวเมนต์โดยตรง ดังนั้นตอนนี้เป็นไปได้ที่จะทำต่อไปนี้:

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

50
น่าสนใจ ดังนั้นสำหรับเราที่มาจาก OO โลกsetชื่อวิธีการค่อนข้างเข้าใจผิด
tishma

3
ถ้าฉันต้องการตั้งหลายหัว ฉันพยายามที่จะแสดงความคิดเห็นHttpHeaders().set(..).set(..)แต่ตอนนี้ส่วนหัวไม่ได้รับการเขียนไปยังเขตข้อมูลส่วนหัว HTTP!
displayname

มันควรปรับการทำงานตามที่ src github.com/angular/angular/blob/master/packages/common/http/src/... ฉันไม่สามารถช่วยคุณได้อีกหากไม่มีข้อมูลเพิ่มเติมเกี่ยวกับปัญหาของคุณ (รหัส)
Jota.Toledo

ดังนั้นในกรณีของฉันฉันทำผิดพลาดโดยการสลับส่วนหัว & params ในรายการอาร์กิวเมนต์ไปยังฟังก์ชัน (เนื่องจากทั้งคู่ยอมรับวัตถุ json) ความหมายก็คือระวังข้อผิดพลาดและ HttpHeaders เนื่องจาก type เป็นแนวปฏิบัติที่ดีหลังจากทั้งหมด .. Off-topic: เมื่อคุณสามารถใช้วัตถุได้ทุกที่อย่าใช้ TypeScript แต่ VanillaJS
อันตราย 89

3
เหตุใดส่วนหัวและคำขอจึงไม่เปลี่ยนแปลง angular.io/guide/http#immutability
Drellgor

23

หากต้องการเพิ่มหลายรายการ params หรือส่วนหัวคุณสามารถทำต่อไปนี้:

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
วิธีนี้ดูเหมือนจะไม่ทำงานเช่นกัน ฉันหมายความว่าคุณสามารถเพิ่มส่วนหัวและพวกเขาจะแสดงในlazyUpdateสถานที่ให้บริการ แต่ในที่สุดมันจะผิดพลาดด้วยCreateListFromArrayLikeข้อยกเว้นเมื่อทำการร้องขอที่มีประสิทธิภาพโดยการสมัครเป็นสมาชิก
จาโก

3
ในการเพิ่มส่วนหัวหลายส่วนให้ใช้: ส่วนหัว: HttpHeaders = new HttpHeaders ({'Application-Id': this.appId, "REST-API-Key": this.apiKey, "content-Type": "application / json"});
Benson

13

ตั้งค่าส่วนหัว http เหมือนด้านล่างในคำขอ http ของคุณ

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

5

ฉันต่อสู้กับสิ่งนี้มาเป็นเวลานาน ฉันใช้ Angular 6 และฉันพบว่า

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

ไม่ทำงาน. แต่สิ่งที่ได้ผลคือ

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

ทำซึ่งทำให้รู้สึกเมื่อคุณรู้ว่าพวกเขาไม่เปลี่ยนรูป ดังนั้นเมื่อสร้างหัวข้อแล้วคุณไม่สามารถเพิ่มหัวข้อนั้นได้ ฉันไม่ได้ลอง แต่สงสัย

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

ก็จะทำงานเช่นกัน


ความพยายามครั้งแรกของคุณควรใช้งานได้คุณกำลังกำหนดผลลัพธ์ของการผนวกเข้ากับตัวแปรส่วนหัว ตอนนี้คำอธิบายของคุณไม่ได้ทำให้ความรู้สึกใด ๆ เป็นพิเศษเดาสุดท้ายของคุณว่าการเพิ่มlet อาจแก้ไขได้
ฆ Mendes

3

ฉันอยู่กับ Angular 8 และสิ่งเดียวที่ทำงานให้ฉันคือ:

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

2

ในคู่มือ ( https://angular.io/guide/http ) ฉันอ่าน: คลาส HttpHeaders ไม่เปลี่ยนรูปดังนั้นทุกชุด () จะส่งคืนอินสแตนซ์ใหม่และใช้การเปลี่ยนแปลง

รหัสต่อไปนี้ใช้ได้กับฉันด้วย angular-4:

 กลับ this.http.get (url, {ส่วนหัว: ใหม่ HttpHeaders (). set ('UserEmail', email)});

0

ในแอปมรดกของฉัน Array.from ของต้นแบบ js ขัดแย้งกับ Array ของเชิงมุมจากที่ทำให้เกิดปัญหานี้ ฉันแก้ไขมันด้วยการบันทึก Array.from ของเวอร์ชันเชิงมุมและกำหนดใหม่หลังจากโหลดต้นแบบ


-3

Angular 8 HttpClient Service ตัวอย่างที่มีการจัดการข้อผิดพลาดและส่วนหัวที่กำหนดเอง

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

      ....
      ....

ป้อนคำอธิบายรูปภาพที่นี่

ตรวจสอบตัวอย่างการสอนที่สมบูรณ์ที่นี่


3
มันเป็นฉันหรือเป็นแบบนี้ overkill สำหรับคำถามที่ถาม?
Ojonugwa Jude Ochalifu

3
นี่ไม่ได้พยายามตอบคำถาม OPs มันเป็นพวงของโค้ดที่ไม่มีคำอธิบายใด ๆ เลย
Jota.Toledo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.