Angular 6使用httpclient问题获取响应标头

Mar*_*non 9 angular angular-httpclient

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

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

代码;

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)

    })
  );
}
Run Code Online (Sandbox Code Playgroud)

但是我的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, …}
Run Code Online (Sandbox Code Playgroud)

我已经看过这个网站和其他人在Angular中正确的方法,但没有用?有人能指出我正确的方向吗?

非常感谢,

标记.

fir*_*ves 18

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

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

    return this.http.get<HttpResponse<Object>>(this.url, {observe: 'response'}).pipe(
         tap(resp => console.log('response', resp))
    );
}
Run Code Online (Sandbox Code Playgroud)

现在在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')))
    );
}
Run Code Online (Sandbox Code Playgroud)

如果您无法访问自定义标头,如上所述,这是因为出于安全原因,默认情况下会向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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,我已禁用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");
Run Code Online (Sandbox Code Playgroud)

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