Angular HttpClient缺少响应标头

时间:2018-09-21 12:23:49

标签: angular angular6 angular-httpclient

我最近试图陷入困境。 我有一个分页的请求。

const myParams = new HttpParams().set('page', page.toString()).set('size', size.toString());
this.http.get<HttpResponse<User[]>>('https://localhost:8443/user/', {
      headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
      params: myParams,
      observe: 'response'
    }).suscribe((response: HttpResponse<User[]>) => this.data = response.body);

DB中元素的总数在X-Total-Count标头中传输到客户端。我试图这样阅读:

.suscribe((response: HttpResponse<User[]>) => {
    this.data = response.body;
    this.totalCount = response.headers.get('X-Total-Count');
});

但这不起作用。事实证明,response.header仅包含实际http-response-header的子集。

这是标题对象的样子

"headers": {
    "normalizedNames": {},
    "lazyUpdate": null
  }

我确定X-Total-Count已发送。 Firefox devtools展示了它。您能告诉我如何将其包含在响应中吗?

enter image description here

更新

此问题与通过以下方式被确定为重复项的问题不同:我一直没有问过如何检查完整的httpResponse。我自己弄清楚了。我一直在问为什么响应的headers属性不完整。

5 个答案:

答案 0 :(得分:3)

为了通过CORS请求访问自定义标头,服务器必须将其明确列入白名单。这可以通过发送以下响应头来完成:

Access-Control-Expose-Headers: X-Total-Count, X-Paging-PageSize

MDN Source

答案 1 :(得分:0)

尝试将CREATE TABLE IF NOT EXISTS store ( id BIGSERIAL PRIMARY KEY ); CREATE TABLE IF NOT EXISTS collection ( id BIGSERIAL PRIMARY KEY, store_id bigint NOT NULL, FOREIGN KEY (store_id) REFERENCES store (id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS item ( id BIGSERIAL PRIMARY KEY, store_id bigint NOT NULL, FOREIGN KEY (store_id) REFERENCES store (id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS collection_item ( id BIGSERIAL PRIMARY KEY, collection_id bigint NOT NULL, item_id bigint NOT NULL, UNIQUE (collection_id, item_id), FOREIGN KEY (collection_id) REFERENCES collection (id) ON DELETE CASCADE, FOREIGN KEY (item_id) REFERENCES item (id) ON DELETE SET NULL ); 添加到http选项对象。

答案 2 :(得分:0)

HttpResponse对象中的标头是延迟加载的,因此headers在您强制加载值之前将显示为空。尝试调用response.headers.keys()以查看所有可用的标头名称。顺便说一句,这还强制将所有值都加载到映射response.headers.headers中。

答案 3 :(得分:0)

正如Tsvetan Ganev之前所述,如果这是CORS请求,则需要按名称在Access-Control-Expose-Headers标头中显式公开必需的标头。为此,您需要配置应用程序服务器,例如在春季使用WebMvcConfigurer时,您可以公开以下标头:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry
                .addMapping("/**")
                .allowedOrigins("*")
                .exposedHeaders("X-Total-Count")
                .allowedMethods("*");
    }
}

使用此配置,您的浏览器将使用7个默认标题以外的内容:

  • Cache-Control
  • Content-Language
  • Content-Length
  • Content-Type
  • Expires
  • Last-Modified
  • Pragma

还将为您的应用程序公开X-Total-Count标头。

答案 4 :(得分:0)

就我而言,Postman 能够获取自定义的“授权”标头,但 Angular 却没有。我通过显式公开自定义标头来解决它

@Bean
public CorsFilter corsFilter() {
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    CorsConfiguration config = new CorsConfiguration();
    config.setAllowCredentials(true);
    config.addAllowedOrigin("*");
    config.addAllowedHeader("*");
    // vvv
    config.addExposedHeader(HttpHeaders.AUTHORIZATION);
    // ^^^
    config.addAllowedMethod(HttpMethod.OPTIONS);
    config.addAllowedMethod(HttpMethod.GET);
    config.addAllowedMethod(HttpMethod.POST);
    config.addAllowedMethod(HttpMethod.PUT);
    config.addAllowedMethod(HttpMethod.PATCH);
    config.addAllowedMethod(HttpMethod.DELETE);
    config.setMaxAge(1800L);
    source.registerCorsConfiguration("/**", config);
    return new CorsFilter(source);
}