从API响应中读取响应标头-Angular 5 + TypeScript


76

我正在触发HTTP请求,并且收到了有效的响应。响应中还有一个X-Token我希望阅读的标题。我正在尝试下面的代码来读取标题,但是,结果是null

this.currentlyExecuting.request = this.http.request(reqParams.type, reqParams.url, {
    body: reqParams.body,
    responseType: 'json',
    observe: 'response'
}).subscribe(
    (_response: any) => {
        // Also tried _response.headers.init();
        const header = _response.headers.get('X-Token');
        console.log(header);
        onComplete(_response.body);
     },
    _error => {
        onComplete({
            code: -1,
            message: Constants.WEBSERVICE_INTERNET_NOT_CONNNECTED
        });
    }
);

API在Chrome inspect中选中时,的响应表明标题存在。

在此处输入图片说明


2
您是否从服务器端公开了X令牌?使用“访问控制公开标头”。因为并非所有标头都允许从客户端访问,所以您需要从服务器端公开它们。
希里希什·羽衣甘蓝

4
如果他在控制台中拥有它,那么可以,他将其公开。

2
@HrishikeshKale:你是对的。Access-Control-Expose-Header有效。您可以将其发布为答案。
萨希尔·坎纳

我已将此发布为答案。快乐的编码:)
赫里希克什·羽衣甘蓝

2
Trichetriche,我不同意。我遇到的情况是我在服务器上添加了标头,并且可以在浏览器控制台中看到它,但浏览器代码看不到它。由于CORS,我必须明确标记它要在浏览器中显示(在我的服务器代码中)。
约翰·吉尔默

Answers:


124

您是否使用过从X-Token服务器端公开了access-control-expose-headers?因为并非所有标头都允许从客户端访问,所以您需要从服务器端公开它们

同样在前端,您可以使用新的HTTP模块来获得完整的响应,{observe: 'response'}例如

http
  .get<any>('url', {observe: 'response'})
  .subscribe(resp => {
    console.log(resp.headers.get('X-Token'));
  });

2
它也适用于post方法吗?我收到错误消息:“在飞行前响应中,Access-Control-Allow-Headers不允许观察请求标头字段。”
KoolKabin

我在哪里可以了解更多信息?这解决了我的问题,但我想知道发生了什么
凯·

@KaiCriticallyAcclaimedCooper是的,请确保这里也是html5rocks.com/en/tutorials/cors链接 ,还有Github问题github.com/angular/angular/issues/6583
Hrishikesh Kale

好答案。谢谢。
Anjana Silva

我仍然无法阅读标题,找到了答案,请参见:stackoverflow.com/questions/58601675/…–
AbolfazlR

18

就我而言 POST我想拥有,authorization header因为我已经拥有了JWT Token。所以我从这篇文章中读到的是我想要的标题,应该Expose Header从后端添加为。因此,我所做的就是将Authorization标头添加到我的“暴露标头”中,如下所示filter class

response.addHeader("Access-Control-Expose-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Authorization, X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept, X-Custom-header");
response.addHeader(HEADER_STRING, TOKEN_PREFIX + token); // HEADER_STRING == Authorization

在我的角度

在组件中。

this.authenticationService.login(this.f.email.value, this.f.password.value)
  .pipe(first())
  .subscribe(
    (data: HttpResponse<any>) => {
      console.log(data.headers.get('authorization'));
    },
    error => {
      this.loading = false;
    });

在我的服务端。

return this.http.post<any>(Constants.BASE_URL + 'login', {username: username, password: password},
  {observe: 'response' as 'body'})
  .pipe(map(user => {
       return user;
  }));

17

您应该使用new HttpClient您可以在此处找到更多信息

http
  .get<any>('url', {observe: 'response'})
  .subscribe(resp => {
    console.log(resp.headers.get('X-Token'));
  });

12

正如Hrishikesh Kale所解释的,我们需要传递Access-Control-Expose-Header。

这里是我们如何在WebAPI / MVC环境中做到这一点:

protected void Application_BeginRequest()
        {
            if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
            {
                //These headers are handling the "pre-flight" OPTIONS call sent by the browser
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
                HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://localhost:4200");
                HttpContext.Current.Response.AddHeader("Access-Control-Expose-Headers", "TestHeaderToExpose");
                HttpContext.Current.Response.End();
            }
        }

另一种方法是,我们可以在webApiconfig.cs文件中添加以下代码。

config.EnableCors(new EnableCorsAttribute("", headers: "", methods: "*",exposedHeaders: "TestHeaderToExpose") { SupportsCredentials = true });

**我们可以在web.config文件中添加自定义标头,如下所示。*

<httpProtocol>
   <customHeaders>
      <add name="Access-Control-Expose-Headers" value="TestHeaderToExpose" />
   </customHeaders>
</httpProtocol>

我们可以创建一个属性,并用该属性修饰该方法。

快乐编码!


1
感谢您的帮助Trilok :)
Anjana Silva,

5

您可以通过以下方式从发布响应标头中获取数据(角度6):

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

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
  observe: 'response' as 'response'
};

this.http.post(link,body,httpOptions).subscribe((res: HttpResponse<any>) => {
  console.log(res.headers.get('token-key-name'));
})

1

您可以使用以下代码获取标题

let main_headers = {}
this.http.post(url,
  {email: this.username, password: this.password},
  {'headers' : new HttpHeaders ({'Content-Type' : 'application/json'}), 'responseType': 'text', observe:'response'})
  .subscribe(response => {
    const keys = response.headers.keys();
    let headers = keys.map(key => {
      `${key}: ${response.headers.get(key)}`
        main_headers[key] = response.headers.get(key)
       }
      );
  });

稍后我们可以从json对象获取所需的标头。

header_list['X-Token']

1

Angular 7服务:

    this.http.post(environment.urlRest +'/ my-operation',body,{标头:标头,观察:“响应”});
    
零件:
    this.myService.myfunction()。subscribe(
          (res:HttpResponse)=> {
              console.log(res.headers.get('x-token'));
                },
        错误=> {
        }) 
    


0

试试这个简单的代码。

1.组件边码:同时获取body和header属性。在主体和Authorization标题中都有一个令牌。

loginUser() {
    this.userService.loginTest(this.loginCred).
    subscribe(res => {
        let output1 = res;
        console.log(output1.body.token);
        console.log(output1.headers.get('Authorization'));
    })
}

2.服务端代码:在正文中发送登录数据,并观察Observable在组件端订阅的任何内容的响应。

loginTest(loginCred: LoginParams): Observable<any> {
    const header1= {'Content-Type':'application/json',};
    const body =  JSON.stringify(loginCred);
    return this.http.post<any>(this.baseURL+'signin',body,{
        headers: header1,
        observe: 'response',
        responseType: 'json'
    });
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.