I've got a binary Excel file created on the server that I'm returning from a C# WebMethod using Convert.ToBase64String(FileData) called from a JavaScript/JQuery $ajax call. I've confirmed the base64 string data gets to the client, but when I attempt to convert it to a binary blob and save it, the bytes saved to disk aren't the same as are on the server. (I'm getting lots of 0xC3 etc. bytes, which look suspiciously like utf8 double byte injections)
$.ajax({
type: "POST",
contentType: "application/json;",
dataType: "json",
processData: false,
data: "{ inputData: \"" + dataString + "\" }",
url: "Api.aspx/GetExcel",
success: ...
success handler code includes:
var excelBlob = new Blob([atob(msg.d)], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;' });
...
var a = document.createElement('a');
...
a.href = window.URL.createObjectURL(excelBlob);
a.setAttribute('download', 'Excel.xlsx');
When it completes download it has bad bytes values. Binary comparison with source shows it's close but has C3 and similar values inserted or munged into place.
Is there something I'm doing wrong or missing to get my Base64 string correctly converted to a client binary blob?
Best Answer
The new Blob constructor encodes any strings it encounters as UTF-8 (http://dev.w3.org/2006/webapi/FileAPI/#constructorBlob). Since you are dealing with binary data this get's converted into UTF-8 multi-byte representations.
Instead you need to convert your data into an array of bytes before passing to the Blob constructor.
The following code works for me in Chrome:
That said I don't know if
atob
is well defined across browsers (I'm guessing there's a reason mozilla provides much longer example code https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding#Solution_.232_.E2.80.93_rewriting_atob%28%29_and_btoa%28%29_using_TypedArrays_and_UTF-8).