Inconsistency between server response size and client blob object size

Viewed 155

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:

  1. the browser sends an AJAX POST to the server
  2. the server creates a ZIP archive using MemoryStream so there’s no physical file in the server
  3. the server returns the ZIP archive in the response’s body
  4. 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.

0 Answers
Related