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

Posted

技术标签:

【中文标题】从 API 响应读取响应标头 - Angular 5 + TypeScript【英文标题】:Read response headers from API response - Angular 5 + TypeScript 【发布时间】:2018-06-19 10:15:54 【问题描述】:

我正在触发一个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 检查中检查时显示标头存在。

【问题讨论】:

您是否从服务器端公开了 x-token?使用“访问控制公开标头”。因为不是所有的头部都允许从客户端访问,你需要从服务器端公开它们。 如果他在控制台中有它,那么是的,他暴露了它。 @HrishikeshKale:你是对的。 Access-Control-Expose-Headers 工作。您可以将此作为答案发布。 我已将此作为答案发布。快乐编码:) 毛毛虫,我不同意。我有一种情况,我在服务器上添加标头并且可以在浏览器控制台中看到它,但浏览器代码看不到它。由于 CORS,我必须明确将其标记为(在我的服务器代码中)暴露给浏览器。 【参考方案1】:

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

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

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

【讨论】:

post 方法是否也一样...我收到错误消息“在预检响应中 Access-Control-Allow-Headers 不允许请求标头字段观察。” 在哪里可以了解更多信息?这解决了我的问题,但我想知道发生了什么 @KaiCriticallyAcclaimedCooper 是的,这里肯定是链接html5rocks.com/en/tutorials/cors,还有 Github 问题github.com/angular/angular/issues/6583 我仍然有阅读标题的问题,我找到了答案,看到这个:***.com/questions/58601675/… 我可以在邮递员中看到标题。这是否意味着标题已暴露?当我使用上面的代码@HrishikeshKale 时,我没有得到那个标题【参考方案2】:

在我的POST 响应中,我想要authorization header,因为我有JWT Token。 所以我从this 帖子中读到的是我想要的标题应该从后端添加为Expose Header。 所以我所做的就是将Authorization 标头添加到我的Exposed Header 中,就像在我的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;
  ));

【讨论】:

【参考方案3】:

您应该使用新的HttpClientYou can find more information here

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

【讨论】:

【参考方案4】:

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

我们如何在 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>

我们可以创建一个属性并使用该属性来装饰方法。

编码愉快!!

【讨论】:

【参考方案5】:

您可以通过这种方式(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】:

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

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']

【讨论】:

【参考方案7】:

角度 7 服务:

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

【讨论】:

【参考方案8】:

试试这个简单的代码。

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

【讨论】:

【参考方案9】:

当从 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();

【讨论】:

以上是关于从 API 响应读取响应标头 - Angular 5 + TypeScript的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 cors 从 angular 2 获取所有响应标头

Angular 5 无法读取来自 Spring 应用程序的响应标头 [重复]

Angular 2:无法访问 http 请求中的响应标头

在 Angular 5 应用程序中响应 Spring Boot 时无法读取授权标头

如何从 Angular 2 响应中获取所有标头?

从跨域 http.get 请求的 ASP.NET Web API 2 响应中获取 Angular 中的特定响应标头(例如 Content-Disposition)