使用ajax 大多得到的数据都是文本形式的,本质是2进制流,浏览器会自动编码,将这些2进制流翻译成文本。
但是有些时候,你想直接得到这些2进制流,不想浏览器进行编码,例如返回图片数据,这个没有对应文本编码,你得到的会是乱码。
在新的浏览器中可以设置ajax对象的responseType属性为arraybuffer,通过response属性来接收2进制流,将得到的数据通过Uint8Array转一下就可以得到2进制流的数组。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
var data= new Uint8Array(this.response);
console.log( data );
};
xhr.send();
在比较老的浏览器中用overrideMimeType函数设置text/plain为charset=x-user-defined,然后把responseText上的字符的ascii编码和0xff相与,就得到2进制的数据。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url', true);
xhr.overrideMimeType('text/plain; charset=x-user-defined');
xhr.onreadystatechange = function(e) {
if (this.readyState == 4 && this.status == 200) {
var binStr = this.responseText;
var data = [];
for (var i = 0, len = binStr.length; i < len; ++i) {
var c = binStr.charCodeAt(i);
var byte = c & 0xff;
data.push( byte );
}
console.log( data );
}
};
xhr.send();
在比较老的IE浏览器中没有overrideMimeType函数,不过responseBody属性已经有2进制数据,但是js没有处理2进制流的函数,需要是用VB来转换下。
var code = "Function IEBinary_getByteAt(strBinary, iOffset)\r\n" + " IEBinary_getByteAt = AscB(MidB(strBinary, iOffset + 1, 1))\r\n" + "End Function\r\n" + "Function IEBinary_getBytesAt(strBinary, iOffset, iLength)\r\n" + " Dim aBytes()\r\n" + " ReDim aBytes(iLength - 1)\r\n" + " For i = 0 To iLength - 1\r\n" + " aBytes(i) = IEBinary_getByteAt(strBinary, iOffset + i)\r\n" + " Next\r\n" + " IEBinary_getBytesAt = aBytes\r\n" + "End Function\r\n" + "Function IEBinary_getLength(strBinary)\r\n" + " IEBinary_getLength = LenB(strBinary)\r\n" + "End Function\r\n"; var jsScript = document.createElement("script"); jsScript.type = "text/vbscript"; try { jsScript.appendChild(document.createTextNode(code)); } catch (e) { jsScript.text = code; } insertAfter(jsScript, document.body); }
var xhr = new XMLHttpRequest();
xhr.open('GET', 'url', true);
xhr.onreadystatechange = function(e) {
if (this.readyState == 4 && this.status == 200) {
var blen = IEBinary_getLength(xhr.responseBody),
data = new VBArray(IEBinary_getBytesAt(xhr.responseBody, 0, len)).toArray();
console.log( data );
}
};
xhr.send();