Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercepting HTTP Response headers with Angular 4.3's HttpInterceptor

This is how I send my HTTP request:

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

I would like to read the HTTP headers of a HttpResponse in my HttpInterceptor:

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
    }
}

The interceptor is provided like this in my app.module.ts:

{ provide: HTTP_INTERCEPTORS, useClass: MyHttpInterceptor, multi: true }

The event seems to have no headers, and even in the Chrome Dev Console I cannot see any headers:

enter image description here

However, when using Postman, I can see the headers in the response (as expected)

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

How can I reveal these headers in Angular ?

The official docs for HTTP says to get the headers like this:

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);
  });
like image 499
Tim Avatar asked Aug 04 '17 14:08

Tim


People also ask

How do you intercept HTTP response?

HttpInterceptor is an interface that can be implemented by a class and it has only one method that intercepts an outgoing HttpRequest and optionally transform it or the response. That method called intercept. Typically an interceptor will transform the outgoing request before returning next. handle(req) .

What is HTTP interceptor in angular?

HTTP Interceptors is a special type of angular service that we can implement. It's used to apply custom logic to the central point between the client-side and server-side outgoing/incoming HTTP request and response. Keep in mind that the interceptor wants only HTTP requests.

Can Angular have multiple HTTP interceptors?

So how can I add multiple interceptors? Http doesn't allow to have more than one custom implementation. But as @estus mentioned the Angular team has added a new HttpClient service recently (release 4.3) which supports multiple interceptors concept. You don't need to extend the HttpClient as you do with the old Http .

How do I use HttpInterceptor?

To use the same instance of HttpInterceptors for the entire app, just import the HttpClientModule into your AppModule, and add the interceptor to the root application injector. Suppose you import HttpClientModule multiple times in different modules (for example, in a lazy-loading module).


4 Answers

I found the answer. It was (of course) a CORS Problem. I am using a CORS Filter and I needed to explicitely expose my custom header. I hope this can help others eventually.

like image 130
Tim Avatar answered Sep 21 '22 04:09

Tim


Looks like a server-side CORS filter configuration.

By default, only the 6 simple response headers are exposed:

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

If you want clients to be able to access other headers, you have to list them using the Access-Control-Expose-Headers header.

Use Access-Control-Expose-Headers to expose the headers.

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

like image 21
Andrea Gherardi Avatar answered Sep 20 '22 04:09

Andrea Gherardi


To see the headers, access the 'headers' within the response. The headers are lazily evaluated it seems, thus they are not visible. I suppose that the headers get evaluated only when you explicitly ask for them using resp.headers.get. However, you can get the list of headers in the response using res.headers.keys(). Eg.

yourFunction.subscribe((res:HttpResponse<any>)=>{console.log('response from server:',res);
      console.log('response headers',res.headers.keys())
    } );
like image 37
Manu Chadha Avatar answered Sep 21 '22 04:09

Manu Chadha


That's not related to Angular. The problem is CORS limits headers by default and you do not see "X-Custom-Header" header when call CORS requests. So, adjust server to let it send X-Custom-Header.

There are TWO different headers that need to be added:

  1. Access-Control-Allow-Headers
  2. Access-Control-Expose-Headers

Access-Control-Allow-Headers must be provided in response of OPTIONS request (pre-flight).

Access-Control-Expose-Headers must be provided in response to the actual (POST/GET) request.

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

like image 34
Durgesh Pal Avatar answered Sep 18 '22 04:09

Durgesh Pal