Angular HttpClient不发送标头

Fre*_*tix 144 http-headers angular angular-httpclient

这是我的代码:

import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
Run Code Online (Sandbox Code Playgroud)
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.');
            }
        }
    );
}
Run Code Online (Sandbox Code Playgroud)

在这里网络调试:

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
Run Code Online (Sandbox Code Playgroud)

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

print_r($_POST);
Array
(
)
Run Code Online (Sandbox Code Playgroud)

我相信错误来自POST期间没有设置的标题,我做了什么错了?

Jot*_*edo 261

HttpHeader类的实例是不可变对象.调用类方法将返回一个新实例作为结果.基本上,您需要执行以下操作:

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

要么

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

更新:添加多个标头

let headers = new HttpHeaders();
headers = headers.set('h1', 'v1').set('h2','v2');
Run Code Online (Sandbox Code Playgroud)

要么

const headers = new HttpHeaders({'h1':'v1','h2':'v2'});
Run Code Online (Sandbox Code Playgroud)

更新:接受HttpClient标头和参数的对象映射

由于5.0.0-beta.6现在可以跳过HttpHeaders对象的创建,因此直接将对象映射作为参数传递.所以现在可以做到以下几点:

http.get('someurl',{
   headers: {'header1':'value1','header2':'value2'}
});
Run Code Online (Sandbox Code Playgroud)

  • 有趣.因此,对于我们来自OO世界,`set`方法名称有点误导. (41认同)
  • 如果我想设置多个标题怎么办?我试图链接注释`HttpHeaders().set(..).set(..)`但是现在再次将头文件写入HTTP头字段?! (3认同)
  • 为什么标头和请求不可变?https://angular.io/guide/http#immutability (2认同)
  • 愚蠢地使其行为不像 https://developer.mozilla.org/en-US/docs/Web/API/Headers/append (2认同)

小智 23

要添加多个参数或标题,您可以执行以下操作:

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 })
Run Code Online (Sandbox Code Playgroud)

  • 要添加多个标头,请使用:headers:HttpHeaders = new HttpHeaders({'Application-Id':this.appId,"REST-API-Key":this.apiKey,"Content-Type":"application/json"}); (3认同)
  • 这个方法似乎也行不通。我的意思是,您可以添加标头,它们将显示在 `lazyUpdate` 属性中,但最终它会在通过订阅使请求生效时因 `CreateListFromArrayLike` 异常而崩溃。 (2认同)

小智 9

在http请求中设置如下所示的http标头

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


Mar*_*ton 7

我为此挣扎了很长时间。我正在使用 Angular 6,我发现

let headers = new HttpHeaders();
headers = headers.append('key', 'value');
Run Code Online (Sandbox Code Playgroud)

不工作。但什么起作用了

let headers = new HttpHeaders().append('key', 'value');
Run Code Online (Sandbox Code Playgroud)

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

let headers = new HttpHeaders();
let headers1 = headers.append('key', 'value');
Run Code Online (Sandbox Code Playgroud)

也会工作。

  • 您的第一次尝试应该有效,您将附加结果分配给 headers 变量。现在你的解释没有任何意义,特别是你最后的猜测是添加一个“let”*可能*可以修复它 (3认同)

Rag*_*hav 6

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

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


小智 5

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

以下代码适用于 angular-4:

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


小智 5

首先,您需要使用 HttpClient 添加 HttpHeaders

import { HttpClient,HttpHeaders  } from '@angular/common/http';
Run Code Online (Sandbox Code Playgroud)

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

constructor(private http: HttpClient) { }
Run Code Online (Sandbox Code Playgroud)

那么你可以这样使用

   let header = new HttpHeaders({ "Authorization": "Bearer "+token});

   const requestOptions = {  headers: header};                                                                                                                                                                            

    return this.http.get<any>(url, requestOptions)
        .toPromise()
        .then(data=> {
            //...
            return data;
    });
Run Code Online (Sandbox Code Playgroud)