Durch Hinzufügen eines HTTP-Headers zum Angular HttpClient wird der Header nicht gesendet. Warum?

178

Hier ist mein Code:

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

und hier das Netzwerk-Debug:

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

und Daten werden in 'Request Payload' gespeichert, aber auf meinem Server wurden die POST-Werte nicht empfangen:

print_r($_POST);
Array
(
)

Ich glaube, der Fehler kommt von dem Header, der während des POST nicht gesetzt wurde. Was habe ich falsch gemacht?

Frennetix
quelle
Ja dank! Nachdem ich jedoch keine Daten in meinem Back-End erhalten hatte, ging ich zu application / x-www-form-urlencoded. Wie auch immer, die Hauptfrage ist anserwerd
Frennetix
Überprüfen Sie dieses Angular 8 HTTPClient-Beispiel, um die RESTFul-API mit benutzerdefiniertem Header und Fehlerbehandlung zu verwenden. Freakyjolly.com/…
Code Spy

Antworten:

306

Die Instanzen der neuen HttpHeaderKlasse sind unveränderliche Objekte. Das Aufrufen von Klassenmethoden gibt als Ergebnis eine neue Instanz zurück. Grundsätzlich müssen Sie also Folgendes tun:

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

oder

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

Update: Hinzufügen mehrerer Header

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

oder

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

Update: Objektzuordnung für HttpClient-Header und -Parameter akzeptieren

Seit 5.0.0-beta.6 ist es nun möglich, die Erstellung eines HttpHeadersObjekts zu überspringen und eine Objektzuordnung direkt als Argument zu übergeben. Jetzt ist es also möglich, Folgendes zu tun:

http.get('someurl',{
   headers: {'header1':'value1','header2':'value2'}
});
Jota.Toledo
quelle
50
Interessant. Für uns aus der OO-Welt ist der setMethodenname also etwas irreführend.
Tishma
3
Was ist, wenn ich mehrere Header setzen möchte? Ich habe versucht, den Kommentar zu verketten, HttpHeaders().set(..).set(..)aber jetzt werden die Header wieder nicht in die HTTP-Headerfelder geschrieben?!
Anzeigename
Es sollte laut src github.com/angular/angular/blob/master/packages/common/http/src/… gut funktionieren . Ich kann Ihnen nicht weiter helfen, ohne weitere Informationen zu Ihrem Problem (Code)
Jota.Toledo
In meinem Fall habe ich also einen Fehler gemacht, indem ich Header und Parameter in der Liste der Argumente auf eine Funktion umgestellt habe (da beide ein JSON-Objekt akzeptiert haben). Das heißt, achten Sie auf Fehler, und HttpHeaders als Typ ist schließlich eine gute Vorgehensweise. Off-Topic: Wenn Sie Objekte überall verwenden können, verwenden Sie nicht TypeScript, sondern VanillaJS.
Gefahr89
3
Warum wurden Header und Anfragen unveränderlich gemacht? angle.io/guide/http#immutability
Drellgor
23

Um mehrere Parameter oder Header hinzuzufügen, können Sie Folgendes tun:

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 })
Hallyson Henrique
quelle
1
Diese Methode scheint auch nicht zu funktionieren. Ich meine, Sie können die Header hinzufügen, und sie werden in der lazyUpdateEigenschaft angezeigt, aber schließlich stürzt sie mit der CreateListFromArrayLikeAusnahme ab, wenn die Anforderung durch Abonnieren wirksam wird.
Jago
3
Um mehrere Header hinzuzufügen, verwenden Sie: headers: HttpHeaders = new HttpHeaders ({'Anwendungs-ID': this.appId, "REST-API-Schlüssel": this.apiKey, "Inhaltstyp": "application / json"});
Benson
13

Stellen Sie http-Header wie unten in Ihrer http-Anfrage ein

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

Ich hatte lange damit zu kämpfen. Ich benutze Angular 6 und habe das gefunden

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

funktioniert nicht. Aber was hat funktioniert?

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

tat, was Sinn macht, wenn Sie erkennen, dass sie unveränderlich sind. Nachdem Sie einen Header erstellt haben, können Sie ihn nicht hinzufügen. Ich habe es nicht versucht, aber ich vermute

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

würde auch funktionieren.

Martin Horton
quelle
Ihr erster Versuch sollte funktionieren. Sie weisen das Ergebnis des Anhängens der Header-Variablen zu. Im Moment macht Ihre Erklärung keinen Sinn, besonders Ihre letzte Vermutung, dass das Hinzufügen von a das let Problem beheben könnte
Juan Mendes
3

Ich war bei Angular 8 und das einzige, was für mich funktionierte, war Folgendes:

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

Im Handbuch ( https://angular.io/guide/http ) habe ich gelesen: Die HttpHeaders-Klasse ist unveränderlich, daher gibt jedes set () eine neue Instanz zurück und wendet die Änderungen an.

Der folgende Code funktioniert für mich mit Angular-4:

 return this.http.get (url, {headers: new HttpHeaders (). set ('UserEmail', email)});
Rob Lassche
quelle
0

In meiner Legacy-App stand Array.from des Prototyps js in Konflikt mit Array.from von Angular, das dieses Problem verursachte. Ich habe es behoben, indem ich die Array.from-Version von Angular gespeichert und nach dem Laden des Prototyps neu zugewiesen habe.

Avinash Wable
quelle
-3

Beispiel für einen Angular 8 HttpClient- Dienst mit Fehlerbehandlung und benutzerdefiniertem Header

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

      ....
      ....

Geben Sie hier die Bildbeschreibung ein

Das vollständige Beispiel-Tutorial finden Sie hier

Code Spy
quelle
3
Bin ich es oder ist das ein bisschen übertrieben für die gestellte Frage?
Ojonugwa Jude Ochalifu
3
Dies versucht nicht, die Frage des OP zu beantworten. Es ist nur ein Haufen Code ohne jegliche Erklärung.
Jota.Toledo