Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create binary blob from atob - currently getting different bytes

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?

like image 887
Joel McIntyre Avatar asked Dec 14 '22 18:12

Joel McIntyre


1 Answers

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:

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.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).

like image 174
Hargo Avatar answered Apr 05 '23 22:04

Hargo