简体   繁体   English

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

[英]Read response headers from API response - Angular 5 + TypeScript

I'm triggering a HTTP<\/code> request and I'm getting a valid response from it.我正在触发一个HTTP<\/code>请求,并且从中得到了有效的响应。 The response also has a header X-Token<\/code> that I wish to read.该响应还有一个我希望阅读的标头X-Token<\/code> 。 I'm trying the below code to read the headers, however, I get null as a result我正在尝试下面的代码来读取标题,但是,结果我得到了 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
        });
    }
);

Have you exposed the X-Token from server side using access-control-expose-headers ?您是否使用access-control-expose-headers从服务器端公开X-Token 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模块来使用{observe: 'response'}获得完整的响应,例如

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

In my case in the POST response I want to have the authorization header because I was having the JWT Token in it.就我而言,在POST响应中,我想要authorization header因为我在其中包含JWT Token So what I read from this post is the header I we want should be added as an Expose Header from the back-end.所以我从这篇文章中读到的是我们想要的标题应该从后端添加为Expose Header So what I did was added the Authorization header to my Exposed Header like this in my filter class .所以我所做的是在我的filter class中将Authorization标头添加到我的Exposed Header中。

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

You should use the new HttpClient .您应该使用新的HttpClient You can find more information here . 您可以在此处找到更多信息

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

As Hrishikesh Kale has explained we need to pass the Access-Control-Expose-Headers.正如 Hrishikesh Kale 所解释的,我们需要传递 Access-Control-Expose-Headers。

Here how we can do it in the WebAPI/MVC environment:这里我们如何在 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();
            }
        }

Another way is we can add code as below in the webApiconfig.cs file.另一种方法是我们可以在 webApiconfig.cs 文件中添加如下代码。

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

**We can add custom headers in the web.config file as below. **我们可以在 web.config 文件中添加自定义标题,如下所示。 * *

<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 !!快乐编码!!

You can get data from post response Headers in this way (Angular 6):您可以通过这种方式(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'));
})

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.稍后我们可以从 json 对象中获取所需的标头。

header_list['X-Token']

Angular 7 Service: Angular 7 服务:

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

Try this simple code.试试这个简单的代码。

1. Components side code: to get both body and header property. 1.组件端代码:获取body和header属性。 Here there's a token in body and Authorization in the 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. Service side code: sending login data in the body and observe the response in Observable any which be subscribed in the component side. 2.服务端代码:在body中发送登录数据,观察组件端订阅的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'
    });
}

I had to do the following to get the headers to appear in SPA Angular application when GETting them from ASP.NET Core service:从 ASP.NET Core 服务获取标头时,我必须执行以下操作才能使标头出现在 SPA Angular 应用程序中:

var builder = WebApplication.CreateBuilder(args);

services.AddCors(options =>
{
    options.AddPolicy("MyExposeResponseHeadersPolicy",
        builder =>
        {
            builder.WithOrigins("https://*.example.com")
                   .WithExposedHeaders("x-custom-header");
        });
});

builder.Services.AddControllers();

var app = builder.Build();

How to read response header when api give error response?当api给出错误响应时如何读取响应头?

by below code i can able to get the response header only when the response is success, in error case also i can able to see "transactionId" header is chrome browser network headers,通过下面的代码,我只能在响应成功时获取响应标头,在错误情况下我也可以看到“transactionId”标头是 chrome 浏览器网络标头,

response = this.httpClient.post(url, reqBody, { headers , observe: 'response'}) .pipe( map(res => { console.log(res.headers.get('transactionId')) return res.body as any; }) ); response = this.httpClient.post(url, reqBody, { headers , observe: 'response'}) .pipe( map(res => { console.log(res.headers.get('transactionId')) return res.body任何; }) );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM