【问题标题】:Adding a HTTP header to the Angular HttpClient doesn't send the header, why?向 Angular HttpClient 添加 HTTP 标头不会发送标头,为什么?
【发布时间】:2017-12-30 09:41:44
【问题描述】:

这是我的代码:

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

并且数据存储在“请求有效负载”中,但在我的服务器中没有收到 POST 值:

print_r($_POST);
Array
(
)

我认为错误来自 POST 期间未设置的标头,我做错了什么?

【问题讨论】:

  • 好的,谢谢!但是在我的后端没有收到数据后,我去了 application/x-www-form-urlencoded。无论如何,主要问题是回答

标签: angular http-headers angular-httpclient


【解决方案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'}
});

【讨论】:

  • 有趣。所以,对于来自 OO 世界的我们来说,set 方法名称有点误导。
  • 如果我想设置多个标题怎么办?我试图链接评论HttpHeaders().set(..).set(..),但现在又没有将标头写入 HTTP 标头字段?!
  • 根据 src github.com/angular/angular/blob/master/packages/common/http/src/… 应该可以正常工作。如果没有有关您的问题(代码)的更多信息,我无法为您提供任何进一步的帮助
  • 所以在我的情况下,我犯了一个错误,将参数列表中的标题和参数切换到函数(因为两者都接受了一个 json 对象)。意思就是要注意错误,毕竟 HttpHeaders 作为类型是一个很好的做法.. 题外话:当你可以在任何地方使用对象时,不要使用 TypeScript 而是使用 VanillaJS。
  • 为什么标头和请求是不可变的? angular.io/guide/http#immutability
【解决方案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 })

【讨论】:

  • 此方法似乎也不起作用。我的意思是,您可以添加标头,它们将显示在lazyUpdate 属性中,但最终它会在通过订阅使请求生效时崩溃并出现CreateListFromArrayLike 异常。
  • 添加多个标头使用: headers:HttpHeaders = new HttpHeaders({ 'Application-Id': this.appId, "REST-API-Key": this.apiKey, "Content-Type": “应用程序/json”});
【解决方案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');
    

    did,当您意识到它们是不可变的时,这是有道理的。因此,创建了一个标题后,您无法添加它。我没试过,但我怀疑

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

    也可以。

    【讨论】:

    • 您的第一次尝试应该有效,您将附加的结果分配给 headers 变量。现在你的解释没有任何意义,特别是你最后的猜测是添加let 可能修复它
    【解决方案5】:

    我使用的是 Angular 8,唯一对我有用的是:

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

    【讨论】:

      【解决方案6】:

      在手册 (https://angular.io/guide/http) 我读到: HttpHeaders 类是不可变的,因此每个 set() 都会返回一个新实例并应用更改。

      以下代码适用于 angular-4:

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

      【讨论】:

        【解决方案7】:

        首先,你需要用HttpClient添加HttpHeaders

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

        你的构造函数应该是这样的。

        constructor(private http: HttpClient) { }
        

        那么你可以这样使用

           let header = new HttpHeaders({ "Authorization": "Bearer "+token});
        
           const requestOptions = {  headers: header};                                                                                                                                                                            
        
            return this.http.get<any>(url, requestOptions)
                .toPromise()
                .then(data=> {
                    //...
                    return data;
            });
        

        【讨论】:

        • 如何获得令牌?
        【解决方案8】:

        在我的原型 js 的旧应用程序 Array.from 与 A​​ngular 的 Array.from 冲突,这导致了这个问题。我通过保存 Angular 的 Array.from 版本并在原型加载后重新分配它来解决它。

        【讨论】:

          【解决方案9】:

          我也在为此苦苦挣扎。我使用了一个拦截器,它捕获响应标头,然后克隆标头(因为标头是不可变对象),然后发送修改后的标头。 https://angular.io/guide/http#intercepting-requests-and-responses

          【讨论】:

            【解决方案10】:

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

            查看完整示例教程here

            【讨论】:

            • 是我还是这个问题有点矫枉过正?
            • 这不是试图回答 OP 的问题。它只是一堆没有任何解释的代码。
            • 这甚至不接近上下文。看起来像是自我推销。
            猜你喜欢
            • 2018-02-04
            • 2012-08-14
            • 2020-04-20
            • 1970-01-01
            相关资源
            最近更新 更多