Подтвердить что ты не робот

Добавление заголовка HTTP к Angular HttpClient не отправляет заголовок, почему?

Вот мой код:

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

и данные хранятся в "Request Payload", но на моем сервере не получены значения POST:

print_r($_POST);
Array
(
)

Я считаю, что ошибка исходит из заголовка, не заданного во время POST, что плохого, что я сделал?

4b9b3361

Ответ 1

Экземпляры нового класса 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'}
});

Ответ 2

Чтобы добавить кратные параметры или заголовки, вы можете сделать следующее:

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

Ответ 3

установите http заголовки, как показано ниже в вашем запросе http

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

Ответ 4

Я долгое время боролся с этим. Я использую 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');

тоже будет работать.

Ответ 5

В руководстве (https://angular.io/guide/http) Я читал: Класс HttpHeaders неизменен, поэтому каждый набор() возвращает новый экземпляр и применяет изменения.

Следующий код работает для меня с angular -4:

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

Ответ 6

В моем устаревшем приложении Array.from из прототипа js конфликтовал с угловым Array.from, который вызывал эту проблему. Я решил это, сохранив угловую версию Array.from и переназначив ее после загрузки прототипа.

Ответ 7

Угловой 7

Я сталкиваюсь с проблемой, устанавливающей заголовки к HttpHeader. Я вижу, что lazyUpdate: {'Content-Type': 'application/json'} заголовков задано lazyUpdate: {'Content-Type': 'application/json'} и headers: {}

Ниже приведен класс HttpHeaders из Angular, где поле 'private headers' нигде не установлено. Полностью застрял

export declare class HttpHeaders {/** * Internal map of lowercase header names to values. */private headers;/** * Internal map of lowercased header names to the normalized * form of the name (the form seen first). */private normalizedNames;/** * Complete the lazy initialization of this object (needed before reading). */private lazyInit;/** * Queued updates to be materialized the next initialization. */private lazyUpdate;/** Constructs a new HTTP header object with the given values.*/constructor(headers?: string | { [name: string]: string | string[]; });/** * Checks for existence of a header by a given name. * * @param name The header name to check for existence. * * @returns Whether the header exits. */has(name: string): boolean;/** * Returns the first header value that matches a given name. * * @param name The header name to retrieve. * * @returns A string if the header exists, null otherwise */get(name: string): string | null;/** * Returns the names of the headers. * * @returns A list of header names. */keys(): string[];/** * Returns a list of header values for a given header name. * * @param name The header name from which to retrieve the values. * * @returns A string of values if the header exists, null otherwise. */getAll(name: string): string[] | null;/** * Appends a new header value to the existing set of * header values. * * @param name The header name for which to append the values. * * @returns A clone of the HTTP header object with the value appended. */append(name: string, value: string | string[]): HttpHeaders;/** * Sets a header value for a given name. If the header name already exists, * its value is replaced with the given value. * * @param name The header name. * @param value Provides the value to set or overide for a given name. * * @returns A clone of the HTTP header object with the newly set header value. */set(name: string, value: string | string[]): HttpHeaders;/** * Deletes all header values for a given name. * * @param name The header name. * @param value The header values to delete for a given name. * * @returns A clone of the HTTP header object. */delete(name: string, value?: string | string[]): HttpHeaders; private maybeSetNormalizedName; private init; private copyFrom; private clone; private applyUpdate; }

Ответ 8

Все приведенные выше предложения великолепны, и ни одно из них не обязательно ошибочно. Но..

... они не полностью согласны с руководством по Angular HTTP.

Согласно веб-сайту Angular, здесь приведен фрагмент кода о том, как добавить HTTP-заголовки к вашему запросу.

import { HttpHeaders } from '@angular/common/http';

const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type':  'application/json',
    'Authorization': 'my-auth-token'
  })
};

this.http.post<Hero>(this.heroesUrl, hero, httpOptions);

Ответ 9

Angular 8 HttpClient Пример службы с обработкой ошибок и пользовательским заголовком

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

      ....
      ....

enter image description here

Ознакомьтесь с полным примером учебника здесь

Ответ 10

Я работал с Angular 8, и единственное, что сработало для меня, это:

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