I've an ASP.NET MVC application that in one page it has a button that when the user click the button in the web browser:
- the browser sends an AJAX POST to the server
- the server creates a ZIP archive using MemoryStream so there’s no physical file in the server
- the server returns the ZIP archive in the response’s body
- the browser gets the response body and creates a BLOB object which is downloaded by the user
Until step 3 everything is working as expected. I have used Fiddler to intercept the server’s response, I created manually a ZIP file with the bytes from the response, and it is OK.
When the user download the file from the web browser it is corrupt. I have realized that the size (length) of the file is bigger than the length of the response’s body.
Here’s the code that generates the response from the server
Response.AppendHeader("Content-Disposition", "attachment; filename=test.zip");
Response.AppendHeader("Content-Length", memoryStream.Length.ToString());
Response.AppendHeader("Content-Type", "application/zip; charset=utf-8");
Response.BinaryWrite(memoryStream.ToArray());
Response.End();
Here’s the code that create and download the file from the server’s response
saveZipFile = (zipFile: any /* zipFile is the server's response */) => {
if (!('Blob' in window)) {
alert('Your browser does not support the HTML5 Blob.');
return;
}
var fileName = "test.zip";
var textFileAsBlob = new Blob([zipFile], { encoding: "UTF-8", type: "application/zip; charset=utf-8" } as any);
if ('msSaveOrOpenBlob' in navigator) {
navigator.msSaveOrOpenBlob(textFileAsBlob, fileName);
} else {
var downloadLink = document.createElement('a');
downloadLink.download = fileName;
downloadLink.innerHTML = 'Download File';
if ('webkitURL' in window) {
// Chrome allows the link to be clicked without actually adding it to the DOM.
downloadLink.href = (window as any).webkitURL.createObjectURL(textFileAsBlob);
} else {
// Firefox requires the link to be added to the DOM before it can be clicked.
downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
downloadLink.onclick = (event: any) => {
document.body.removeChild(event.target);
};
downloadLink.style.display = 'none';
document.body.appendChild(downloadLink);
}
downloadLink.click();
}
}
If you need more details, please let me know.
What can be wrong?
PD: I think it’s related to string encoding.