Read response headers from API response - Angular

2020-01-20 11:07发布

问题:

I'm triggering a HTTP request and I'm getting a valid response from it. The response also has a header X-Token that I wish to read. I'm trying the below code to read the headers, however, I get null as a result

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

The response of the API, when checked in Chrome inspect, shows the header is present.

回答1:

Have you exposed the X-Token from server side using access-control-expose-headers? because not all headers are allowed to be accessed from the client side, you need to expose them from the server side

Also in your frontend, you can use new HTTP module to get a full response using {observe: 'response'} like

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


回答2:

You should use the new HttpClient. You can find more information here.

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


回答3:

In my case in the POST response I want to have the authorization header because I was having the JWT Token in it. So what I read from this post is the header I we want should be added as an Expose Header from the back-end. So what I did was added the Authorization header to my Exposed Header like this in my 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

And at my Angular Side

In the Component.

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

At my Service Side.

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


回答4:

As Hrishikesh Kale has explained we need to pass the Access-Control-Expose-Headers.

Here how we can do it in the WebAPI/MVC environment:

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

Another way is we can add code as below in the webApiconfig.cs file.

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

**We can add custom headers in the web.config file as below. *

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

we can create an attribute and decore the method with the attribute.

Happy Coding !!



回答5:

You can get data from post response Headers in this way (Angular 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'));
})


回答6:

You can get headers using below code

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

later we can get the required header form the json object.

header_list['X-Token']


回答7:

Angular 7 Service:

    this.http.post(environment.urlRest + '/my-operation',body, { headers: headers, observe: 'response'});
    
Component:
    this.myService.myfunction().subscribe(
          (res: HttpResponse) => {
              console.log(res.headers.get('x-token'));
                }  ,
        error =>{
        })