L'ajout d'un en-tête HTTP à Angular HttpClient n'envoie pas l'en-tête, pourquoi?

181

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

et ici le débogage du réseau:

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

et les données sont stockées dans 'Request Payload' mais dans mon serveur ne reçoit pas les valeurs POST:

print_r($_POST);
Array
(
)

Je crois que l'erreur vient de l'en-tête non défini lors du POST, qu'est-ce que j'ai fait de mal?

Frennetix
la source
Oui merci! Mais après ne pas avoir reçu de données sur mon Back-end, je suis allé à application / x-www-form-urlencoded. Quoi qu'il en soit, la question principale est répondue
Frennetix
Consultez cet exemple Angular 8 HTTPClient pour consommer l'API RESTFul avec un en-tête personnalisé et une gestion des erreurs freakyjolly.com
Code Spy

Réponses:

310

Les instances de la nouvelle HttpHeaderclasse sont des objets immuables . L'appel des méthodes de classe renverra une nouvelle instance comme résultat. Donc, fondamentalement, vous devez faire ce qui suit:

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

ou

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

Mise à jour: ajout de plusieurs en-têtes

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

ou

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

Mise à jour: accepter la mappe d'objets pour les en-têtes et paramètres HttpClient

Depuis la version 5.0.0-beta.6, il est désormais possible de sauter la création d'un HttpHeadersobjet et de passer directement une carte d'objets en argument. Alors maintenant, il est possible de faire ce qui suit:

http.get('someurl',{
   headers: {'header1':'value1','header2':'value2'}
});
Jota.Toledo
la source
50
Intéressant. Donc, pour nous venant du monde OO, le setnom de la méthode est quelque peu trompeur.
tishma
3
Que faire si je souhaite définir plusieurs en-têtes? J'ai essayé d'enchaîner le commentaire HttpHeaders().set(..).set(..)mais maintenant encore les en-têtes ne sont pas écrits dans les champs d'en-tête HTTP?!
displayname
Cela devrait fonctionner correctement selon le src github.com/angular/angular/blob/master/packages/common/http/src/… . Je ne peux pas vous aider davantage sans plus d'informations sur votre problème (code)
Jota.Toledo
Donc, dans mon cas, j'ai fait une erreur en changeant les en-têtes et les paramètres de la liste des arguments vers une fonction (puisque les deux ont accepté un objet json). Ce qui signifie qu'il suffit de faire attention aux erreurs, et HttpHeaders en tant que type est une bonne pratique après tout. Hors sujet: lorsque vous pouvez utiliser des objets partout, n'utilisez pas TypeScript mais VanillaJS.
danger89
3
Pourquoi les en-têtes et les demandes sont-ils devenus immuables? angular.io/guide/http#immutability
Drellgor
23

Pour ajouter plusieurs paramètres ou en-têtes, vous pouvez effectuer les opérations suivantes:

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
la source
1
Cette méthode ne semble pas non plus fonctionner. Je veux dire, vous pouvez ajouter les en-têtes, et ils s'afficheront dans la lazyUpdatepropriété, mais finalement cela plantera à l' CreateListFromArrayLikeexception de la mise en vigueur de la demande en vous y abonnant.
Jago
3
Pour ajouter plusieurs en-têtes, utilisez: headers: HttpHeaders = new HttpHeaders ({'Application-Id': this.appId, "REST-API-Key": this.apiKey, "Content-Type": "application / json"});
Benson
13

définissez les en-têtes http comme ci-dessous dans votre requête http

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

J'ai lutté avec ça pendant longtemps. J'utilise Angular 6 et j'ai trouvé que

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

n'a pas marché. Mais ce qui a fonctionné était

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

fait, ce qui a du sens lorsque vous réalisez qu'ils sont immuables. Donc, après avoir créé un en-tête, vous ne pouvez pas y ajouter. Je ne l'ai pas essayé, mais je soupçonne

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

fonctionnerait aussi.

Martin Horton
la source
Votre première tentative devrait fonctionner, vous affectez le résultat de l'ajout à la variable headers. Pour le moment, votre explication n'a aucun sens, en particulier votre dernière supposition que l'ajout d'un let peut résoudre le problème
Juan Mendes
3

J'étais avec Angular 8 et la seule chose qui a fonctionné pour moi était la suivante:

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

Dans le manuel ( https://angular.io/guide/http ) j'ai lu: La classe HttpHeaders est immuable, donc chaque set () retourne une nouvelle instance et applique les changements.

Le code suivant fonctionne pour moi avec angular-4:

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

Dans mon ancienne application, Array. De prototype js était en conflit avec Array. De angular qui causait ce problème. Je l'ai résolu en sauvegardant la version Array.fr d'angular et en la réaffectant après le chargement du prototype.

Avinash Wable
la source
-3

Exemple de service Angular 8 HttpClient avec gestion des erreurs et en- tête personnalisé

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

      ....
      ....

entrez la description de l'image ici

Consultez l'exemple de tutoriel complet ici

Espion de code
la source
3
Est-ce moi ou est-ce un peu exagéré pour la question posée?
Ojonugwa Jude Ochalifu
3
Cela ne tente pas de répondre à la question des OP. C'est juste un tas de code sans aucune explication.
Jota.Toledo