14

I cannot get a specific header (Content-Disposition) when I'm accessing it via an Angular service. CORS is enabled and the Angular HTTPClient is set to retrieve ALL headers.

Startup.cs

 public void Configuration(IAppBuilder app)
        {

            HttpConfiguration config = new HttpConfiguration();
            WebApiConfig.Register(config);
            ConfigureOAuth(app, config);
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(config);
 } 

fileController.cs

[Route("file/{idFile}")]
        public HttpResponseMessage GetFile(string idFile)
        {
            string file;
            byte[] file;

            document = fileService.GetFile(idDFile, out fileName);

            var result = new HttpResponseMessage(HttpStatusCode.OK)
            {
                Content = new ByteArrayContent(file)
            };
            result.Content.Headers.ContentDisposition =
                new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                {
                    FileName = nomeFile
                };
            result.Content.Headers.ContentType =
                new MediaTypeHeaderValue("application/octet-stream");

            return result;
        }

fileService.ts

getFile(fileId: number): Observable<Response> {
        const url = `${urlBackEnd}/file/${fileId}`;
        return this.http.get(url, { observe: 'response', responseType: 'blob' })
          .map(res => {;
            console.log(res.headers.keys()); // There's no CONTENT-DISPOSITION
            saveAs(<Blob>res.body);
            return res.body;
          })
          .catch(e => this.handleErrors(e));
}

Here's the header console.log:

[
  "content-type",
  "cache-control"
]

What am I missing? I just want to get the Content-Disposition header.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Dyd666
  • 705
  • 1
  • 11
  • 30
  • The server you’re sending the cross-origin request to must include na Access-Control-Expose-Headers header in the response, with Content-Disposition in its value. See the answer at https://stackoverflow.com/questions/39020385/fetch-api-not-returning-the-location-header/39021128#39021128 – sideshowbarker Dec 05 '17 at 11:42
  • Thanks @sideshowbarker, i tried doing that but still, i cannot get that header. https://i.imgur.com/NemwLRb.png `result.Content.Headers.Add("Access-Control-Expose-Headers", "*");` – Dyd666 Dec 05 '17 at 14:42
  • 1
    I think browsers don’t yet support the `*` wildcard value for the Access-Control-Expose-Headers. Try instead explicitly listing Content-Disposition in the value. – sideshowbarker Dec 05 '17 at 14:44
  • see this: https://stackoverflow.com/questions/58601675/angular-how-to-get-headers-value-in-the-canactive-function/58602196#58602196 – Abolfazl Roshanzamir Oct 30 '19 at 06:22

2 Answers2

25

In the fileController.cs file, along with setting the Content-Type and Content-Disposition response headers, you need to set Access-Control-Expose-Headers:

result.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");

Note that while the Fetch spec does actually allow "*" as the value of Access-Control-Expose-Headers (though that’s not very clear from reading the current spec text…) — browsers don’t yet conform to the spec on that; so instead you should explicitly list all response header names the browser should expose to your frontend JavaScript code — except for Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, and Pragma, which are always exposed. For any response headers other than those six and the ones you explicitly list in the value of the Access-Control-Expose-Headers header, browsers block frontend code from accessing them.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
  • 2
    Don't know if it matters too much -- I had to use the hyphenated name: `Content-Disposition` :: `result.Content.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");` – Mark Headley May 11 '18 at 17:42
  • @MarkHeadley Yeah it does make a difference. So I edited the answer to correct that — thanks for catching that so that I could fix it – sideshowbarker May 11 '18 at 22:13
-1
 httpServletResponse.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
 httpServletResponse.setHeader(Content-Disposition,getFileName());

This solution working for me.

Avinash Dalvi
  • 8,551
  • 7
  • 27
  • 53
Dhammadip
  • 87
  • 1
  • 4