Last active
April 26, 2024 08:13
-
-
Save abbotto/5a78b0094a395b860759 to your computer and use it in GitHub Desktop.
Get binary data with XHR in most browsers including IE8+
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* xhrBinary.js | |
* Author: Jared Abbott | |
* Copyright 2015 Jared Abbott | |
* Distributed under the MIT license | |
*/ | |
var xhrBinary = function(url, fn) { | |
// RESOURCES | |
// http://mgran.blogspot.com/2006/08/downloading-binary-streams-with.html | |
// http://miskun.com/javascript/internet-explorer-and-binary-files-data-access/ | |
// http://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string | |
// https://msdn.microsoft.com/en-us/library/y39d47w8(v=VS.85).aspx | |
// https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data | |
// USAGE | |
// xhrBinary(url, function(data){ | |
// // Encode the string w/ Base64 | |
// var base64 = 'data:application/octet-stream;base64,'+btoa(data); | |
// }); | |
var request = window.XMLHttpRequest || ActiveXObject; | |
var xhr = new request("MSXML2.XMLHTTP.3.0"); | |
var data = ''; | |
var buffer = ''; | |
var bufferLength = 0; | |
// Retrieve the file | |
xhr.open('GET', url, true); | |
// XMLHttpRequest2-compliant browsers | |
if (!!window.Uint8Array) { | |
xhr.responseType = "arraybuffer"; | |
} | |
// XMLHttpRequest-compliant browsers | |
else if ('overrideMimeType' in xhr) { | |
xhr.overrideMimeType('text\/plain; charset=x-user-defined'); | |
} | |
// Microsoft.XMLHTTP-compliant browsers [IE9] | |
else { | |
xhr.setRequestHeader('Accept-Charset', 'x-user-defined'); | |
} | |
xhr.onreadystatechange = function(e) { | |
if (this.readyState == 4 && this.status == 200) { | |
// Handles most browsers with a fallback for IE9 | |
if (!!window.Uint8Array || !!window.VBArray) { | |
// In IE9 and below the responseBody property returns a byte array in VBArray format | |
// VBArray is not directly usable 'as is' with JavaScript. | |
// In IE9+ we can access the bytes by converting the VBArray to a JS-compatible array | |
// with the VBArray.toArray() method. | |
buffer = (!!window.Uint8Array) ? new Uint8Array(xhr.response) : xhr.responseBody.toArray(); | |
data = String.fromCharCode.apply(null, buffer); | |
} | |
// IE8 | |
else if (!!window.execScript) { | |
buffer = xhr.responseBody; | |
var parseVBArray = function (buffer) { | |
// VBScript | |
var VBScript = | |
"Function binToArrByteStr(buffer)\r\n"+ | |
" binToArrByteStr = CStr(buffer)\r\n"+ | |
"End Function\r\n"+ | |
"Function binToArrByteStr_Last(buffer)\r\n"+ | |
" Dim lastIndex\r\n"+ | |
" lastIndex = LenB(buffer)\r\n"+ | |
" if lastIndex mod 2 Then\r\n"+ | |
" binToArrByteStr_Last = AscB( MidB( buffer, lastIndex, 1 ) )\r\n"+ | |
" Else\r\n"+ | |
" binToArrByteStr_Last = -1\r\n"+ | |
" End If\r\n"+ | |
"End Function\r\n"; | |
// Execute VBScript | |
window.execScript(VBScript); | |
// Mapper | |
var byteMapping = {}; | |
for ( var i = 0; i < 256; i++ ) { | |
for ( var j = 0; j < 256; j++ ) { | |
byteMapping[String.fromCharCode(i + j * 256)] = String.fromCharCode(i) + String.fromCharCode(j); | |
} | |
} | |
// Data | |
var rawBytes = binToArrByteStr(buffer); | |
var lastChr = binToArrByteStr_Last(buffer); | |
return rawBytes.replace(/[\s\S]/g, function( match ) { return byteMapping[match]; }) + lastChr; | |
} | |
data = parseVBArray(buffer); | |
} | |
// Other browsers | |
else { | |
buffer = xhr.responseText; | |
bufferLength = buffer.length; | |
for (var i = 0, len = bufferLength; i < len; ++i) { | |
// Throw away high-order bytes at offset i (f7) | |
data += String.fromCharCode(buffer.charCodeAt(i) & 255) // 255 === 0xff | |
} | |
} | |
// Return the binary | |
if (typeof fn !== 'undefined') { | |
fn(data); | |
} else { | |
return data; | |
} | |
} | |
}; | |
xhr.send(null); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment