how to read content-disposition headers from server response angular 2
Asked Answered
A

9

52

I am unable to find, how to read filename from content disposition in angular 2 documentation. Can someone guide read the headers from server in angular 2content headers

Aloes answered 20/3, 2017 at 7:40 Comment(0)
C
20

You can try this kind of code here.

Note: Do not use map

this.http.post(URL, DATA)
  .subscribe((res) => {
     var headers = res.headers;
     console.log(headers); //<--- Check log for content disposition
     var contentDisposition = headers.get('content-disposition');
});
Cartercarteret answered 20/3, 2017 at 8:10 Comment(5)
Thanks @Partha Sarathi Ghosh for your great reply, it also seems to be working with map methodAloes
How to reach the same with Promise ?Buddle
doesn't work for me. Only content-type is in the headersStuffed
not working for me also. Only content-type is in the headersCalamint
res.headers is undefined for me, but I can find filename in content-disposition of headerMisogynist
C
88

With new Angular Http, one can try the following in the Service code.

  downloadLink(): Observable<HttpResponse<Blob>> {
    return this.http.get<Blob>(this.someURL, {
      observe: 'response',
      responseType: 'blob' as 'json'
    });
  }

And use the above as

 this.someService
  .downloadLink()
  .subscribe(
    (resp: HttpResponse<Blob>) => {
      console.log(resp.headers.get('content-disposition'));
      data = resp.body
    });

Also, on the server side, one needs to set the following header in response. 'Access-Control-Expose-Headers': 'Content-Disposition'

Like in Java Spring Boot one can do the same using

    final HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=1.xlsx");
    headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_DISPOSITION);
Cutinize answered 16/6, 2018 at 10:58 Comment(5)
Thanks Nehal! This helped me. I was not exposing headers in response.Protagoras
adding observe: 'response' makes my zip file corruptedFetial
adding response type corrupting dataHavana
added on the server side as well,this is what i get in header keys ["cache-control", "content-length", "content-type", "expires", "pragma"] but in browser ACCESS_CONTROL_EXPOSE_HEADERS: CONTENT_DISPOSITION and CONTENT_DISPOSITION: abc.xml is present in my response headersHavana
for .NET Core app.Use((ctx, next) => { ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*");Marshallmarshallese
D
55

To those complaining that the best solution is not working, and only content-type is in the headers, you need to set 'Access-Control-Expose-Headers': 'Content-Disposition' ON SERVER SIDE. I am using asp.net core, then I have to do the following.

app.UseCors(builder =>
                builder.WithOrigins(originsAllowed.ToArray())
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .WithExposedHeaders("Content-Disposition")
Directrix answered 16/4, 2018 at 23:46 Comment(0)
B
35

In angular, we can read File Name like as show below,

  this.http.post(URL, DATA).subscribe(
        (res) => {
            var contentDisposition = res.headers.get('content-disposition');
            var filename = contentDisposition.split(';')[1].split('filename')[1].split('=')[1].trim();
            console.log(filename);
        });

But the main thing is that we need to specify Access-Control-Expose-Header in API as shown below,

Note: The last line is mandatory

FileInfo file = new FileInfo(FILEPATH);

HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
    FileName = file.Name
};
response.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
Breastsummer answered 28/3, 2019 at 6:13 Comment(2)
Please note that the code above is missing a replacement for the quotes which appear if the filename has custom characters in the name. You should add .replace(/\"/g, '') after .trim()Tude
This will only work if the filename is the [1] element in the disposition string.Guyette
C
20

You can try this kind of code here.

Note: Do not use map

this.http.post(URL, DATA)
  .subscribe((res) => {
     var headers = res.headers;
     console.log(headers); //<--- Check log for content disposition
     var contentDisposition = headers.get('content-disposition');
});
Cartercarteret answered 20/3, 2017 at 8:10 Comment(5)
Thanks @Partha Sarathi Ghosh for your great reply, it also seems to be working with map methodAloes
How to reach the same with Promise ?Buddle
doesn't work for me. Only content-type is in the headersStuffed
not working for me also. Only content-type is in the headersCalamint
res.headers is undefined for me, but I can find filename in content-disposition of headerMisogynist
L
11

With Angular 9 and Expresss

Need to Allow this header in Express

res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');

Angular

this.http.get(url, { observe: 'response', responseType: 'blob' as 'json' })
.subscribe((res: any) => {
    console.log(res.headers.get('content-disposition'));
});
Lesson answered 11/3, 2020 at 9:19 Comment(1)
for .NET Core app.Use((ctx, next) => { ctx.Response.Headers.Add("Access-Control-Expose-Headers", "*"); Marshallmarshallese
B
4

In Angular 7 the up-voted method don't work, you need to do it like this :

const responseHeaderFilename = response.headers.get('content-disposition');

Please find Angular official docs for more details: https://angular.io/guide/http#reading-the-full-response

and also make sure that the "Content-Disposition" is exposed as in @mslugx answer

Basifixed answered 13/3, 2019 at 15:24 Comment(0)
C
3

To get the filename from response header.

(data)=>{  //the 'data' is response of file data with responseType: ResponseContentType.Blob.
    let filename = data.headers.get('content-disposition').split(';')[1].split('=')[1].replace(/\"/g, '')
}
Curtiscurtiss answered 24/7, 2020 at 5:12 Comment(2)
This will only work if the filename is the [1] element in the disposition string.Guyette
Alternative : decodeURI(response.headers.get('content-disposition')?.match(/(?<=filename(?:=|\*=(?:[\w\-]+'')))["']?(?<filename>[^"';\n]+)["']?/g)?.pop()?.replace(/\"/g, ''))Uboat
U
2

CORS requests only expose 6 headers :

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

In order to access custom headers with a CORS request, the server has to explicitly whitelist them. This can be done by sending the response header: Access-Control-Expose-Headers

Java : addExposedHeader https://docs.spring.io/spring-framework/docs/4.2.x/javadoc-api/org/springframework/web/cors/CorsConfiguration.html

.NET CORE : WithExposedHeaders https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-6.0

Express JS : exposedHeaders https://expressjs.com/en/resources/middleware/cors.html

Uboat answered 2/2, 2022 at 13:22 Comment(0)
C
2

Angular 12 with parsing of the file name.

const saveAsWithServerName = (response: HttpResponse<Blob>, defaultName = 'NoName.pdf') => {
  const fileName = response.headers
    .get('content-disposition')
    .split(';')
    .map(h => h.trim())
    .filter(h => h.startsWith('filename='))
    .reduce(h => h.length === 1 ? h[0] : defaultName)
    .replace('filename=', '');
  saveAs(response.body, fileName);
};

this.http.post(`./api/ReportPdf`, request, {observe: 'response', responseType: 'blob'}).subscribe({
    next: r => saveAsWithServerName(r)
});
Condescending answered 1/3, 2023 at 20:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.