Angular 6获取带有httpclient问题的响应标头

Posted

技术标签:

【中文标题】Angular 6获取带有httpclient问题的响应标头【英文标题】:Angular 6 Get response headers with httpclient issue 【发布时间】:2019-12-21 11:09:11 【问题描述】:

我正在使用下面的代码尝试从响应标头中提取一个值(ReturnStatus);

Keep-Alive: timeout=5, max=100
ReturnStatus: OK,SO304545
Server: Apache/2.4.29 (Win32) OpenSSL/1.0.2m

代码;

import  Injectable  from '@angular/core';

import  Account  from './model/account';
import  HttpClient  from '@angular/common/http';
import  Observable, throwError  from "rxjs";
import  map, filter, catchError, mergeMap  from 'rxjs/operators';

 createOrder(url) : Observable<any> 

  return this._http.get(url, withCredentials: true, observe: 'response')
  .pipe(
    map((resp: any) => 
      console.log("response", resp);
      return resp;

    ), catchError( error => 
      console.log("createOrder error",error );
      alert("Create Order Service returned an error. See server log for mote details");
    return throwError("createOrder: " + error)

    )
  );

但是我的 console.log 只是给;

HttpResponse headers: HttpHeaders, status: 200, statusText: "OK", url: 
"http://localhost/cgi-bin/dug.cgi/wh?Page… 
plateLocation=C:%5Ctemp%5Corderimporttemplate.txt", ok: true, …

我在这个网站和其他网站上查看了在 Angular 中执行此操作的正确方法,但无济于事? 有人能指出我正确的方向吗?

非常感谢,

标记。

【问题讨论】:

你的问题是什么?您在哪里尝试获取响应状态并且它失败了? 它不会失败,因此我只是想找到正确的方法来到达响应标头中的 ReturnStatus 行。 【参考方案1】:

您需要观察整个响应,如下所述:

 createOrder(url) : Observable<HttpResponse<Object>>

    return this.http.get<HttpResponse<Object>>(this.url, observe: 'response').pipe(
         tap(resp => console.log('response', resp))
    );

现在在 resp 中你可以访问标题 一个例子

 createOrder(url) : Observable<HttpResponse<Object>>

    return this.http.get<HttpResponse<Object>>(this.url, observe: 'response').pipe(
         tap(resp => console.log('heaeder', resp.headers.get('ReturnStatus')))
    );

如果您无法按照上述说明访问自定义标头,那是因为出于安全原因,默认情况下一小部分标头会暴露给 javascript。 如果您打开开发人员工具并检查响应标头,您应该会看到所需的标头。

谁可以选择向 javascript 公开哪些标头?

公开的标头由 Web 应用程序选择(因此您的 Web 服务或后端。显然,您的 Web 应用程序可以使用多种语言和/或多种框架编写。

根据您使用的内容,您可以通过不同的方式实现此目标。

为了让您了解应该做什么,我可以发布我的 Spring 解决方案。 在扩展WebSecurityConfigurerAdapter 的类中,您应该添加这两个方法:

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception 
    httpSecurity
            // we don't need CSRF because our token is invulnerable
            .csrf().disable()
            .cors()
 


@Bean
public CorsFilter corsFilter() 
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addExposedHeader("Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
            "Content-Type, Access-Control-Request-Method, Custom-Filter-Header");
    config.addAllowedHeader("*");
    config.addAllowedMethod("OPTIONS");
    config.addAllowedMethod("GET");
    config.addAllowedMethod("POST");
    config.addAllowedMethod("PUT");
    config.addAllowedMethod("DELETE");
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);

请注意,我已禁用 csrf,因为我使用的是 JWT。 请注意,您应该细化 CorsFilter 规则。

如您所见,我已将Custom-Filter-Header 添加到此行

config.addExposedHeader("Authorization, x-xsrf-token, Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, " +
                "Content-Type, Access-Control-Request-Method, Custom-Filter-Header");

你可以用你的ReturnStatus替换这个Custom-Filter-Header

【讨论】:

嗨。谢谢你。不幸的是,看起来可能还需要其他一些东西,因为这是一个自定义标题? github.com/angular/angular/issues/5237 详细说明向 API 添加“Access-Control-Expose-Headers”... 如果您没有使用 spring,请告诉我,如果可以,我应该帮助您解决后端问题 :) 非常感谢为这个问题提供帮助。目前我们通过返回一个 XML 响应并对其进行解析来围绕它进行编码 配置中的关键内容 - 观察:“响应”为“正文”。水龙头是多余的 如果有人在服务器上使用 CORS 和 ASP.NET,您必须在配置 CORS 时使用暴露的Headers 参数显式公开标头值。

以上是关于Angular 6获取带有httpclient问题的响应标头的主要内容,如果未能解决你的问题,请参考以下文章

带有 HttpClient 的 Angular 异步函数

Angular 6 和 Spring boot - 无法使用简单的 HttpClient 调用获取数据

Angular 6 HTTPClient:请求触发一次,收到2个响应

如何在 Angular 6 中使用 HttpClient 禁用缓存

带有 .Get() 对 Azure 搜索 API 的请求的 Angular HttpClient“未知错误”

在 Angular 6 中使用 HttpClient 下载文件