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 pletes download it has bad bytes values. Binary parison 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?
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 pletes download it has bad bytes values. Binary parison 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?
Share Improve this question asked Dec 2, 2014 at 0:11 Joel McIntyreJoel McIntyre 932 silver badges5 bronze badges1 Answer
Reset to default 16The new Blob constructor encodes any strings it encounters as UTF-8 (http://dev.w3/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:
var binary = atob(base64)
var array = new Uint8Array(binary.length)
for( var i = 0; i < binary.length; i++ ) { array[i] = binary.charCodeAt(i) }
new Blob([array])
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/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).