Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Angular's new HttpClient, how can I get all headers when subscribing to the events?

Tags:

angular

I am using Angular 4.3.2 and the new HttpClient to download a file sent as a stream, and I need to get the headers (particularly, Content-Disposition), but they don't seem to be present in the response even though I can see the headers being correctly sent with the request in Chrome's dev tools.

This is the code:

downloadDocument(documentId: number) {
    const downloadDocumentUrl = `${ this.config.apiUrls.documents }/${ documentId }`;
    const downloadRequest = new HttpRequest('GET', downloadDocumentUrl, {
        reportProgress: true,
        responseType: 'blob'
    });

    let percentageDownloaded = 0;
    this.http.request(downloadRequest).subscribe(
        (event: HttpEvent < any > ) => {
            if (event) {
                switch (event.type) {
                    case HttpEventType.ResponseHeader:
                        const contentDispositionHeader = event.headers.get('Content-Disposition');
                        console.log(contentDispositionHeader); // Always null here although I expected it to be there.
                        break;

                    case HttpEventType.DownloadProgress:
                        if (event.total) {
                            percentageDownloaded = Math.round((event.loaded / event.total) * 100);
                        }
                        break;

                    case HttpEventType.Response:
                        const downloadedFile: Blob = event.body;
                        fileSaverSaveAs(downloadedFile, `${ documentId }.pdf`, true); // This is where I'd like to use content-disposition to use the actual file name.
                        break;
                }
            }
         ,
        (err) => {}
    );
}

When this code gets called, Chrome reports in the network tab of dev tools the following response headers:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:4200
Content-Disposition:attachment; filename=doc5619362.pdf; filename*=UTF-8''doc5619362.pdf
Content-Length:88379
Content-Type:application/pdf
Date:Thu, 03 Aug 2017 09:43:41 GMT
Server:Kestrel
Vary:Origin
X-Powered-By:ASP.NET

Any ideas on how I can access all the headers present in the response? It is not just Content-Disposition that is not present, all of the other headers are not there except for Content-Type.

Thanks!

UPDATE

Here is a working Plunker demonstrating the issue: https://plnkr.co/edit/UXZuhWYKHrqZCZkUapgC?p=preview

like image 443
Ceottaki Avatar asked Aug 03 '17 09:08

Ceottaki


People also ask

What is the use of HttpClient get () method?

Use the HttpClient.get() method to fetch data from a server. The asynchronous method sends an HTTP request, and returns an Observable that emits the requested data when the response is received. The return type varies based on the observe and responseType values that you pass to the call.

What is Access Control expose headers?

The Access-Control-Expose-Headers response header allows a server to indicate which response headers should be made available to scripts running in the browser, in response to a cross-origin request. Only the CORS-safelisted response headers are exposed by default.

What data format is the response from the HttpClient get () method and how do you read its contents?

The responseType option indicates the format of the data returns from the http request. Default responseType of HttpClient. get() method is “json”. Every http response contains http response headers and body.


1 Answers

The problem is not Angular, is the CORS handshaking: If the server does not explicitly allow your code to read the headers, the browser will hide them from it. The server must add in its responses the header Access-Control-Expose-Headers:<header_name>,<header-name2> in order to let you to read them, but currently it only allows to do a request and to read the response's body by adding Access-Control-Allow-Origin

like image 108
Pablo Lozano Avatar answered Oct 06 '22 01:10

Pablo Lozano