29

In this page http://www.html5rocks.com/en/tutorials/file/dndfiles/ if you scroll down to example "Example: Slicing a file. Try it!" you will see uses of readAsBinaryString API to read bytes of local files.

I've seen IE (My case its IE11) doesn't support readAsBinaryString.

Even this code mentioned in post HTML5 File API read as text and binary breaks at readAsBinaryString in IE11.

I have seen some post in stack overflow, it suggests use of ReadAsArrayBuffer(). But it is also not working. It returns undefined.

My question is what are the options if I have to run it on IE11? Is it possible to write another IE compatible JS function which will do the JOB of readAsBinaryString().

asked Jul 13, 2015 at 18:52

6 Answers 6

52

I combine @Jack answer with my comment to show a complete working example.

In the <head> section I added this script to add FileReader.readAsBinaryString function in IE11

if (FileReader.prototype.readAsBinaryString === undefined) {
 FileReader.prototype.readAsBinaryString = function (fileData) {
 var binary = "";
 var pt = this;
 var reader = new FileReader();
 reader.onload = function (e) {
 var bytes = new Uint8Array(reader.result);
 var length = bytes.byteLength;
 for (var i = 0; i < length; i++) {
 binary += String.fromCharCode(bytes[i]);
 }
 //pt.result - readonly so assign content to another property
 pt.content = binary;
 pt.onload(); // thanks to @Denis comment
 }
 reader.readAsArrayBuffer(fileData);
 }
}

Then I needed to slightly modify my original script code because target.result has no value when using this fallback function.

var reader = new FileReader();
reader.onload = function (e) {
 // ADDED CODE
 if (!e) {
 var data = reader.content;
 }
 else {
 var data = e.target.result;
 }
 // business code
};
reader.readAsBinaryString(myFile);
answered Feb 3, 2016 at 7:28

5 Comments

$(pt).trigger('onload'); is it jQuery's trigger method? How to do dispatch this event without jQuery?
Jack + Naigel = Just saved my day
@Denis added your suggestion, it was the only code line requiring jQuery and was easy to change with vanilla JS.
@NachPD glad to help someone else, I've already wasted hours on that point, let's make them worthy ;)
Why not always use e.target.result? Is !e ever true?
36

This is my solution.

var reader = new FileReader();
reader.readAsBinaryString(fileData);
reader.onload = function(e) {
 if (reader.result) reader.content = reader.result;
 var base64Data = btoa(reader.content);
 //...
}
//extend FileReader
if (!FileReader.prototype.readAsBinaryString) {
 FileReader.prototype.readAsBinaryString = function (fileData) {
 var binary = "";
 var pt = this;
 var reader = new FileReader(); 
 reader.onload = function (e) {
 var bytes = new Uint8Array(reader.result);
 var length = bytes.byteLength;
 for (var i = 0; i < length; i++) {
 binary += String.fromCharCode(bytes[i]);
 }
 //pt.result - readonly so assign binary
 pt.content = binary;
 $(pt).trigger('onload');
 }
 reader.readAsArrayBuffer(fileData);
 }
}
answered Sep 19, 2015 at 6:48

3 Comments

in the main code I was using FileReader this way: var reader = new FileReader(); reader.onload = function (e) { var data = e.target.result; ..CODE HERE.. }; reader.readAsBinaryString(myFile). I needed to change reader.onload this way: reader.onload = function (e) { if (!e) {var data = reader.content;} else {var data = e.target.result; } ..CODE HERE.. };
@Naigel comment was very helpful with the change he wrote. combining Jacks code and Naigels worked for me
$(pt).trigger('onload'); is it jQuery's trigger method? How to do dispatch this event without jQuery?
9

FileReader.readAsBinaryString is a non-standard function and has been deprecated.

FileReader.readAsArrayBuffer should be used instead.

MDN

answered Nov 1, 2017 at 6:26

Comments

7

For IE 11 you can use this XHR trick:

function blobToBinaryStringIE11(blob) {
 var blobURL = URL.createObjectURL(blob);
 var xhr = new XMLHttpRequest;
 xhr.open("get", blobURL);
 xhr.overrideMimeType("text/plain; charset=x-user-defined");
 xhr.onload = function () {
 var binary = xhr.response;
 // do stuff
 };
 xhr.send();
}

It's 20x faster than the Uint8Array + fromCharCode route and as fast as readAsBinaryString.

answered Jun 11, 2016 at 17:39

Comments

1

Replace

reader.readAsBinaryString(blob);

with:

reader.readAsText(blob);

it's works well in cross browser.

answered Jul 11, 2017 at 7:42

1 Comment

There are problems with this. Since the browser thinks its text and not binary it can cause errors for example in firefox I got invalid characters error.
0

I had some problems with the answers here and ended up making a few slight changes.

Instead of assigning to pt.content, my solution is to send a custom object to the prototype's onload, that receiver can specifically look for, I named this property msieContent so it will be very specific.

Also I used other accepted answer for converting Uint8Array to string in more robust way, you can see full details of it here: https://stackoverflow.com/a/12713326/213050

Polyfill

if (FileReader.prototype.readAsBinaryString === undefined) {
 // https://stackoverflow.com/a/12713326/213050
 function Uint8ToString(u8a: Uint8Array) {
 const CHUNK_SZ = 0x8000;
 let c = [];
 for (let i = 0; i < u8a.length; i += CHUNK_SZ) {
 c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
 }
 return c.join('');
 }
 FileReader.prototype.readAsBinaryString = function (fileData) {
 const reader = new FileReader();
 reader.onload = () => this.onload({
 msieContent: Uint8ToString(new Uint8Array(<any>reader.result))
 });
 reader.readAsArrayBuffer(fileData);
 }
}

Usage

private _handleTextFile(file: File) {
 const reader = new FileReader();
 reader.onload = (e) => {
 // support for msie, see polyfills.ts
 const readResult: string = (<any>e).msieContent || <string>e.target.result;
 };
 reader.readAsBinaryString(file);
}
answered Apr 16, 2020 at 18:12

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.