使用 Angular 4.3 的 HttpInterceptor 拦截 HTTP 响应标头

Posted

技术标签:

【中文标题】使用 Angular 4.3 的 HttpInterceptor 拦截 HTTP 响应标头【英文标题】:Intercepting HTTP Response headers with Angular 4.3's HttpInterceptor 【发布时间】:2018-01-12 13:55:16 【问题描述】:

这就是我发送 HTTP 请求的方式:

return this.http.get(url,  observe: 'response' )

我想在我的 HttpInterceptor 中读取 HttpResponse 的 HTTP 标头

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> 
        return next.handle(request)
            .do(event => 
                if (event instanceof HttpResponse) 
                    this.logger.logDebug(event); // Headers are missing here
                
            )
            .catch((err: HttpErrorResponse) => 
            // Do stuff
    

拦截器在我的 app.module.ts 中这样提供

提供:HTTP_INTERCEPTORS, 使用类:MyHttpInterceptor, 多:真

该事件似乎没有标头,即使在 Chrome 开发控制台中我也看不到任何标头:

但是,当使用 Postman 时,我可以在响应中看到标题(如预期的那样)

Connection →keep-alive
Content-Length →14766
Content-Type →application/json
Date →Fri, 04 Aug 2017 14:50:46 GMT
Server →WildFly/10
X-Powered-By →Undertow/1

如何在 Angular 中显示这些标题?

HTTP 的官方docs 说要获取这样的标头:

http
  .get<MyJsonData>('/data.json', observe: 'response')
  .subscribe(resp => 
    // Here, resp is of type HttpResponse<MyJsonData>.
    // You can inspect its headers:
    console.log(resp.headers.get('X-Custom-Header'));
    // And access the body directly, which is typed as MyJsonData as requested.
    console.log(resp.body.someField);
  );

【问题讨论】:

如何注册这个拦截器? 我编辑了我的帖子,添加了这些信息 Angular 的响应中记录了什么? 我添加了响应截图 查看HttpHeaders 文档。有一个 get() 和一个 getAll() 方法。 angular.io/api/common/http/HttpHeaders 【参考方案1】:

我找到了答案。这(当然)是一个 CORS 问题。我正在使用CORS Filter,我需要明确地公开我的自定义标头。我希望这最终可以帮助其他人。

【讨论】:

感谢蒂姆,它让 CORS 业务变得疯狂。对于任何对 Spring Boot 感兴趣的人,您必须将您的标头名称添加到 CorsRegistry 上的exposedHeaders 方法中。【参考方案2】:

看起来像服务器端 CORS 过滤器配置。

默认情况下,只公开 6 个简单的响应头:

缓存控制 内容-语言 内容类型 过期 最后修改 编译指示

如果您希望客户端能够访问其他标头,则必须 使用 Access-Control-Expose-Headers 标头列出它们。

使用 Access-Control-Expose-Headers 公开标头。

来源:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

【讨论】:

【参考方案3】:

要查看标头,请访问响应中的“标头”。标题似乎被懒惰地评估,因此它们不可见。我想只有当您使用resp.headers.get 明确要求它们时,才会评估标题。但是,您可以使用res.headers.keys() 获取响应中的标头列表。例如。

yourFunction.subscribe((res:HttpResponse<any>)=>console.log('response from server:',res);
      console.log('response headers',res.headers.keys())
     );

【讨论】:

【参考方案4】:

这与 Angular 无关。问题是 CORS 默认限制标头,并且在调用 CORS 请求时看不到“X-Custom-Header”标头。所以,调整服务器让它发送 X-Custom-Header。

需要添加两个不同的标题:

    Access-Control-Allow-Headers Access-Control-Expose-Headers

Access-Control-Allow-Headers 必须提供以响应 OPTIONS 请求(飞行前)。

Access-Control-Expose-Headers 必须提供以响应实际 (POST/GET) 请求。

Access-Control-Expose-Headers: X-Custom-Header

【讨论】:

以上是关于使用 Angular 4.3 的 HttpInterceptor 拦截 HTTP 响应标头的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4.3 - HTTP 拦截器 - 刷新 JWT 令牌

如何在测试中模拟 Angular 4.3 httpClient 的错误响应

如何使用 Angular cli 升级 Angular 的次要版本

如何使用角度 4.3 中的新 httpClient 处理未经授权的请求(状态为 401 或 403)

在 Angular 5 中禁用 zone.js 后,ngOnInit 未触发

在 Angular Reactive Forms 中的 FormGroup 实例上设置错误无法按预期工作