javascript - How to download file with certain name, set in .NET Core controller method, using Vue.js?
问题描述
I have defined an endpoint which returns a file to my front-end project. The endpoint is shown below:
[HttpGet("{shipmentId:int}/pod")]
public async Task<IActionResult> GetShipmentPodAsync([FromRoute] int shipmentId)
{
try
{
var result = await QueryBus
.SendAsync<GetShipmentPodQuery, PodFile>(
new GetShipmentPodQuery
{
ShipmentId = shipmentId
});
return File(result.Content, result.Type, result.FileName);
}
catch (Exception e)
{
// ToDo: Handle exception in proper way
return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
}
}
The following function is responsible for communication with mentioned endpoint:
async getPodFile(shipmentId) {
const resource = `shipment/${shipmentId}/pod`;
await client.getFile(resource)
.then((result) => {
const fileUrl = window.URL.createObjectURL(new Blob([result.data]));
const a = document.createElement('a');
document.body.appendChild(a);
a.style = 'display: none';
a.href = fileUrl;
a.download = `test.pdf`;
a.click();
window.URL.revokeObjectURL(fileUrl);
document.body.removeChild(a);
});
},
I would like to use file name returned from my API, but i have no idea how to access it after receiving a response (I've tried to log a response object, but found no field like "filename"). How to use name, taken from the server instead of the hard-coded one?
解决方案
我找到了解决方案 - CORS 阻止了包含文件名的标头。我必须将 WithExposedHeaders 添加到我的 CORS 配置中:
private const string ContentDispositionHeaderName = "Content-Disposition";
internal static IServiceCollection ConfigureResourceSharing(this IServiceCollection services,
IConfiguration configuration)
{
var originsContainer = configuration
.GetSection(AllowedOriginsSectionName)
.Get<ICollection<string>>();
return services
.AddCors(o =>
{
o.AddPolicy(PolicyName,
b =>
{
foreach (var origin in originsContainer)
{
b.WithOrigins(origin)
.WithExposedHeaders(ContentDispositionHeaderName)
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
}
});
});
}
添加这一行,解决了问题,文件名可以从这个标题中获得:)