L'aggiunta di un'intestazione HTTP a Angular HttpClient non invia l'intestazione, perché?


181

Ecco il mio codice:

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

e qui il debug della rete:

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

e i dati sono memorizzati in "Richiedi payload" ma nel mio server non sono stati ricevuti i valori POST:

print_r($_POST);
Array
(
)

Credo che l'errore provenga dall'intestazione non impostata durante il POST, cosa ho fatto di sbagliato?


Sì grazie! Ma dopo non aver ricevuto i dati sul mio back-end, sono passato a application / x-www-form-urlencoded. Comunque la domanda principale è anserwerd
Frennetix,

Controlla questo esempio Angular 8 HTTPClient per utilizzare l'API RESTFul con intestazione personalizzata e gestione degli errori freakyjolly.com/…
Codice spia

Risposte:


311

Le istanze della nuova HttpHeaderclasse sono oggetti immutabili . Il richiamo dei metodi di classe restituirà una nuova istanza come risultato. Quindi, in pratica, devi fare quanto segue:

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

o

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

Aggiornamento: aggiunta di più intestazioni

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

o

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

Aggiornamento: accetta la mappa degli oggetti per le intestazioni e i parametri di HttpClient

Poiché 5.0.0-beta.6 è ora possibile saltare la creazione di un HttpHeadersoggetto e passare direttamente una mappa di oggetti come argomento. Quindi ora è possibile fare quanto segue:

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

50
Interessante. Quindi, per noi provenienti dal mondo OO, il setnome del metodo è in qualche modo fuorviante.
tishma,

3
Cosa succede se desidero impostare più intestazioni? Ho provato a concatenare il commento HttpHeaders().set(..).set(..)ma ora le intestazioni non vengono scritte nei campi dell'intestazione HTTP ?!
displayname

Dovrebbe funzionare bene secondo src github.com/angular/angular/blob/master/packages/common/http/src/… . Non posso aiutarti ulteriormente senza ulteriori informazioni sul tuo problema (codice)
Jota.Toledo,

Quindi nel mio caso ho commesso un errore commutando header e parametri nell'elenco di argomenti in una funzione (poiché entrambi hanno accettato un oggetto json). Il significato è solo fare attenzione agli errori, e HttpHeaders come tipo è una buona pratica dopo tutto. Fuori tema: quando puoi usare oggetti ovunque, non usare TypeScript ma VanillaJS.
danger89,

3
Perché intestazioni e richieste sono state rese immutabili? angular.io/guide/http#immutability
Drellgor

23

Per aggiungere parametri multipli o intestazioni è possibile effettuare le seguenti operazioni:

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
Anche questo metodo non sembra funzionare. Voglio dire, puoi aggiungere le intestazioni, che verranno visualizzate nella lazyUpdateproprietà, ma alla fine si bloccherà con l' CreateListFromArrayLikeeccezione quando renderà effettiva la richiesta iscrivendoti ad essa.
Jago,

3
Per aggiungere più intestazioni usa: headers: HttpHeaders = new HttpHeaders ({'ID applicazione': this.appId, "REST-API-Key": this.apiKey, "Content-Type": "application / json"});
Benson,

13

imposta le intestazioni http come di seguito nella tua richiesta http

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

5

Ho lottato con questo per molto tempo. Sto usando Angular 6 e l'ho trovato

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

non ha funzionato. Ma cosa ha funzionato

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

fatto, il che ha senso quando ti rendi conto che sono immutabili. Quindi, avendo creato un'intestazione non è possibile aggiungervi. Non l'ho provato, ma sospetto

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

funzionerebbe anche.


Il tuo primo tentativo dovrebbe funzionare, stai assegnando il risultato dell'appendice alla variabile headers. In questo momento la tua spiegazione non ha alcun senso, specialmente la tua ultima ipotesi che l'aggiunta di un let può risolverlo
Juan Mendes,

3

Ero con Angular 8 e l'unica cosa che ha funzionato per me è stata questa:

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

2

Nel manuale ( https://angular.io/guide/http ) ho letto: La classe HttpHeaders è immutabile, quindi ogni set () restituisce una nuova istanza e applica le modifiche.

Il seguente codice funziona per me con angular-4:

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

0

Nella mia app legacy Array.from del prototipo js era in conflitto con Array.from di Angular che causava questo problema. L'ho risolto salvando la versione Array.from di angular e riassegnandola dopo il caricamento del prototipo.


-3

Esempio di servizio HttpClient angolare 8 con gestione degli errori e intestazione personalizzata

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

      ....
      ....

inserisci qui la descrizione dell'immagine

Controlla l'esercitazione completa di esempio qui


3
Sono io o questo è un po 'eccessivo per la domanda posta?
Ojonugwa Jude Ochalifu,

3
Questo non sta tentando di rispondere alla domanda dei PO. È solo un mucchio di codice senza alcuna spiegazione.
Jota.Toledo,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.