Dodanie nagłówka HTTP do Angular HttpClient nie powoduje wysłania nagłówka, dlaczego?

181

Oto mój kod:

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

a tutaj debug sieciowy:

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

a dane są przechowywane w „Request Payload”, ale na moim serwerze nie otrzymałem wartości POST:

print_r($_POST);
Array
(
)

Uważam, że błąd pochodzi z nagłówka nie ustawionego podczas POST, co zrobiłem źle?

Frennetix
źródło
Tak, dziękuję! Ale po nieotrzymaniu danych na moim Back-end, przeszedłem do application / x-www-form-urlencoded. W każdym razie główne pytanie jest anserwerd
Frennetix
Sprawdź ten kątowa 8 httpclient przykład spożywać spokojny API z niestandardowego nagłówka i obsługi błędów freakyjolly.com/...
Code Spy

Odpowiedzi:

311

Instancje nowej HttpHeaderklasy są niezmiennymi obiektami. Wywołanie metod klasy zwróci jako wynik nową instancję. Zasadniczo musisz wykonać następujące czynności:

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

lub

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

Aktualizacja: dodawanie wielu nagłówków

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

lub

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

Aktualizacja: zaakceptuj mapę obiektów dla nagłówków i parametrów HttpClient

Od wersji 5.0.0-beta.6 jest teraz możliwe pominięcie tworzenia HttpHeadersobiektu i bezpośrednie przekazanie mapy obiektów jako argumentu. Więc teraz można wykonać następujące czynności:

http.get('someurl',{
   headers: {'header1':'value1','header2':'value2'}
});
Jota.Toledo
źródło
50
Ciekawy. Tak więc dla nas pochodzących ze świata OO setnazwa metody jest nieco myląca.
tishma
3
Co jeśli chcę ustawić wiele nagłówków? Próbowałem połączyć komentarz, HttpHeaders().set(..).set(..)ale teraz znowu nagłówki nie są zapisywane w polach nagłówka HTTP ?!
nazwa wyświetlana
Powinien działać dobrze zgodnie z src github.com/angular/angular/blob/master/packages/common/http/src/… . Nie mogę Ci dalej pomóc bez dodatkowych informacji o Twoim problemie (kod)
Jota.Toledo
Więc w moim przypadku popełniłem błąd, przełączając nagłówki i parametry na liście argumentów na funkcję (ponieważ obie zaakceptowały obiekt json). Oznacza to, że po prostu uważaj na błędy, a HttpHeaders jako typ jest w końcu dobrą praktyką ... Nie na temat: kiedy możesz używać obiektów wszędzie, nie używaj TypeScript, ale VanillaJS.
niebezpieczeństwo89
3
Dlaczego nagłówki i żądania stały się niezmienne? angular.io/guide/http#immutability
Drellgor
23

Aby dodać wielokrotności parametrów lub nagłówków, możesz wykonać następujące czynności:

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
źródło
1
Ta metoda również nie działa. Chodzi mi o to, że możesz dodać nagłówki i pojawią się one we lazyUpdatewłaściwości, ale ostatecznie ulegnie awarii, z CreateListFromArrayLikewyjątkiem sytuacji, gdy żądanie będzie skuteczne, subskrybując je.
Jago
3
Aby dodać wiele nagłówków, użyj: headers: HttpHeaders = new HttpHeaders ({'Application-Id': this.appId, "REST-API-Key": this.apiKey, "Content-Type": "application / json"});
Benson,
13

ustaw nagłówki http jak poniżej w swoim żądaniu http

return this.http.get(url, { headers: new HttpHeaders({'Authorization': 'Bearer ' + token})
 });
rajamallareddys
źródło
5

Walczyłem z tym przez długi czas. Używam Angular 6 i znalazłem to

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

nie działał. Ale to, co zadziałało, było

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

zrobił, co ma sens, gdy zdajesz sobie sprawę, że są niezmienne. Więc po utworzeniu nagłówka nie możesz go dodać. Nie próbowałem tego, ale podejrzewam

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

zadziała też.

Martin Horton
źródło
Twoja pierwsza próba powinna zadziałać, przypisujesz wynik dopisywania do zmiennej headers. W tej chwili twoje wyjaśnienie nie ma żadnego sensu, szczególnie twoje ostatnie przypuszczenie, że dodanie let może to naprawić
Juan Mendes
3

Byłem z Angular 8 i jedyną rzeczą, która działała dla mnie, było to:

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

W instrukcji ( https://angular.io/guide/http ) przeczytałem: Klasa HttpHeaders jest niezmienna, więc każda set () zwraca nową instancję i wprowadza zmiany.

Poniższy kod działa dla mnie z angular-4:

 return this.http.get (url, {headers: new HttpHeaders (). set ('UserEmail', email)});
Rob Lassche
źródło
0

W mojej starszej aplikacji Array.from of prototype js był w konflikcie z Array.from firmy angular, który był przyczyną tego problemu. Rozwiązałem to, zapisując Array.z wersji angulara i przypisując go ponownie po załadowaniu prototypu.

Avinash Wable
źródło
-3

Przykład usługi HttpClient Angular 8 z obsługą błędów i niestandardowym nagłówkiem

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

      ....
      ....

wprowadź opis obrazu tutaj

Sprawdź pełny przykładowy samouczek tutaj

Code Spy
źródło
3
Czy to ja, czy to trochę przesada jak na zadane pytanie?
Ojonugwa Jude Ochalifu
3
To nie jest próba odpowiedzi na pytanie PO. To tylko zbiór kodu bez żadnego wyjaśnienia.
Jota.Toledo