I have a C# backend generating a zip file in memory (with System.IO.Compression) and sending it to my front end. If I download the zip file before sending it, it is working well and is in ANSI encoding (found on notepad++).
This is how I return my file currently, I have tried many different ways to do it, such as simply returning a file without headers, but right now it looks like this :
[HttpPost]
[Route("GetUserWorkContext")]
public async Task<IActionResult> GetUserWorkContext([FromBody] GetUserWorkContextRequest request, [FromServices] IExportManager exportManager)
{
var zipStream = await exportManager.GetUserWorkContext(userId, request.IncludeArchived);
HttpContext.Response.Headers.Add("Content-Disposition", "attachment; filename = test.zip; charset=Windows-1252");
HttpContext.Response.Headers.Add("Content-Length", zipStream.ToArray().Length.ToString());
return File(zipStream.ToArray(), "application/octet-stream");
}
It seems that no matter how I download the file with Javascript (front-end), it is saved with utf8 encoding (found with notepad++ again). I tried using js-file-download ( https://www.npmjs.com/package/js-file-download ) or creating blobs, but anything I end up downloading is encoded in utf8.
How should I go about downloading this file in Javascript without corrupting the archive ?
Here is my current attempt in Javascript, using a piece of code I found here (JavaScript blob filename without link) to download the file :
function getUserWorkContext({ includeArchived }) {
return new Promise(function () {
Axios.post('/api/Export/GetUserWorkContext', {includeArchived})
.then((response) => {
if(response.data){
var blobObject = new Blob([response.data], {type: 'application/zip;charset=Windows-1252'});
downloadFile(blobObject, "test.zip");
}
})
}
function downloadFile(file, fileName) {
if (navigator.msSaveBlob) { // For ie and Edge
return navigator.msSaveBlob(file, fileName);
}
else {
let link = document.createElement('a');
link.href = window.URL.createObjectURL(file);
link.download = fileName;
document.body.appendChild(link);
link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window }));
link.remove();
window.URL.revokeObjectURL(link.href);
}
}
Note : the actual zip is 3,747KB where as the download zip from Javascript is always much bigger, in this case : 6,917KB.
This is a problem with axios:
I guess, you should use blob
or arraybuffer
as responseType
for axios.
{ responseType: 'blob' }
//
responseType
indicates the type of data that the server will respond with // options are: 'arraybuffer', 'document', 'json', 'text', 'stream' // browser only: 'blob'
responseType: 'json'
// default
Check this answer: https://stackoverflow.com/a/60461828/2487565
=== 8< ======================= previous version ======================= 8< ===
Your Content-Disposition
header is wrong. There is no charset
parameter for Content-Disposition
header.
Check the docs: MDN HTTP Content-Disposition
That's why your file is still sent in UTF-8, since your charset
parameter has no effect.
To use UTF-8:
Delete both Content- headers from C# and the charset parameter from JavaScript
var blobObject = new Blob([response.data], {type: 'application/zip'});
If you really need to use Windows-1252
, you can try to set it with the content type parameter.
return File(zipStream.ToArray(), "application/octet-stream;charset=Windows-1252");
Check this also: Charset Encoding in ASP.NET Response
By the way, UTF-8 is the preferred charset encoding: W3 QA choosing encodings
And, yes @nikneem, there is no need in the Content-Disposition
and Content-Length
headers. They will be generated automatically.