Reputation: 735
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.
Upvotes: 15
Views: 13649
Reputation: 652
I fixed this by adjusting my CORS rule defined in the server (ASP.NET Core 8) to look like this
var corsPolicy = new CorsPolicyBuilder()
.WithOrigins(builder.Configuration["FrontendUrl"])
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithExposedHeaders(HeaderNames.ContentDisposition)
.Build();
builder.Services.AddCors(options => options.AddPolicy("wasm", corsPolicy));
When exposing the "Content-Disposition", you can also read it in your client.
Upvotes: 1
Reputation: 87
httpServletResponse.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
httpServletResponse.setHeader(Content-Disposition,getFileName());
This solution working for me.
Upvotes: -1
Reputation: 88186
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.
Upvotes: 27