As we all know, JavaScript does not support binary files and data. The traditional approach is to convert a binary file into a character, and then convert the corresponding string into a number in a browser using some techniques (the traditional method will be described later ). This processing method is not standard and requires some "tricks" or even "spoofing" browsers.
With the evolution of browsers, new solutions have emerged. XMLHttpRequest Level 2 supports binary data upload and download. It can be used with file system API and web audio API. Our new solution uses this feature.
This is a demo.
Xhr2 Solution
XMLHttpRequest Level 2 introduces the responsetype and response attributes, which notify the browser to process the requested data in a certain format.
-
Xhr. responsetype
-
Before sending a request, set xhr. responsetype to 'text', 'arraybuffer', 'blob ', or 'document '. The default value is 'text '.
-
Xhr. Response
-
After obtaining the data, according to the previous value of responsetype, the response attribute of xhr is data in domstring, arraybuffer, blob, or document format.
Using the preceding two attributes, We Can format binary data into arraybuffer instead of a string. Then, use the blobbuilder API to convert data to blob for processing:
?
1234567891011121314151617 |
Blobbuilder = Window. Empty blobbuilder | window. webkitblobbuilder | window. blobbuilder;
VaR Xhr = New XMLHttpRequest (); Xhr. Open ( 'Get' , '/Path/to/image.png' , True ); Xhr. responsetype = 'Arraybuffer' ; Xhr. onload = Function
(E ){ If ( This . Status = 200 ){ VaR BB = New Blobbuilder (); BB. append ( This . Response ); // Note: Not xhr. responsetext
VaR Blob = BB. getblob ( 'Image/PNG' ); ... } }; Xhr. Send (); |
This makes processing much easier. By using arraybufferview, we can process data more conveniently. It encapsulates arraybuffer data so that we can process the requested binary data like an array. View has several formats: float32array, float64array, int16array, int32array, int8array, uint16array, uint32array, and uint8array. In my opinion, processing binary data uint8array should be the most convenient. Below isCodeExample:
?
12345678910111213 |
VaR Xhr = New XMLHttpRequest (); Xhr. Open ( 'Get' , '/Path/to/image.png' , True ); Xhr. responsetype = 'Arraybuffer' ; Xhr. onload = Function (E ){ VaR Uint8array = New Uint8array ( This . Response ); // This. Response = uint8array. Buffer VaR Byte3 = uint8array [4]; // Byte at offset 4 If (Byte3 = 0xa9 ){ Alert ( 'The first data is 0xa9'
); } }; Xhr. Send (); |
Its Requirements for browsers are firefox6 + and chrome9 +. What about other low-version browsers? Downgrading traditional solutions
Traditional Solution
The traditional solution is to rewrite the MIME type to a custom charset when requesting data. Then, each byte in the request data is processed and matched with 0xff to obtain 8-bit data. Example:
?
123456789101112131415161718 |
VaR Xhr = New XMLHttpRequest (); Xhr. Open ( 'Get' , '/Path/to/image.png'
, True ); // Hack to pass bytes through unprocessed. Xhr. overridemimetype ( 'Text/plain; charset = x-user-defined' ); Xhr. onreadystatechange = Function (E ){ If ( This . Readystate = 4 && This
. Status = 200 ){ VaR Binstr = This . Responsetext; For ( VaR I = 0, Len = binstr. length; I <Len; ++ I ){ VaR C = binstr. charcodeat (I ); // String. fromcharcode (C & 0xff );
VaR Byte = C & 0xff; // Byte at offset I } } }; Xhr. Send (); |
By setting the mimetype technique, we get a string representing binary data, and then process the string to get the data we think. This method is not recommended, because it forces the character to be converted into the format we need each time, and uses tips to cheat the browser.
IE Solution
Ie9-The overridemimetype method is not supported. What should I do? A few days ago, ququ'sArticleThe "front-end Implementation Scheme for automatic image rotation" mentioned the use of VB for data processing. I tried it. There are many byte processing functions in VB. Here we only use three:
-
Midb
-
Returns a part of a string. Result = midb (source string, start point, [length]). midb treats the source string as a group of bytes rather than a group of characters. Midb should be used when the source string represents binary data.
-
ASCB
-
ASCB returns the first byte. It is used with midb to obtain the bytes at the specified position in the data.
-
Lenb
-
Obtains the total number of bytes in a string. The lenb function treats a string as a group of bytes rather than a group of characters. This function is used when a string represents binary data.
With these three functions, we can obtain the bytes of the string corresponding to the Ajax request. The following is an example of the excerpt code:
?
123456789101112131415161718 |
Document. Write ( & Quot; <SCRIPT type = 'Text/vbscript' > \ R \ n " +" 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 " +" </SCRIPT> \ r \ n & quot; ); |
This code has passed document. write method. Two or three VB functions are inserted in the page. iebinary_getbyteat returns the bytes at the specified position. iebinary_getbytesat returns the array of bytes of the specified length starting from the specified position, iebinary_getlength returns the number of bytes in the string. We can use these three functions to process the strings in Ajax responsebody to obtain the corresponding binary data.
Note: In earlier versions of IE, JS processing capabilities are not strong, so if the data to be processed is too large, it is easy to cause CPU 100% or even browser crashes.
Code example:
?
1234567891011121314 |
VaR Xhr = New Activexobject ( "Microsoft. XMLHTTP" ); Xhr. onreadystatechange = Function (){ If (Xhr. readystate = 4 ){ If (Xhr. Status = "200" | Xhr. Status = "206" | Xhr. Status = "0" ){ VaR Blen = iebinary_getlength (xhr. responsebody ), Bytearray = New Vbarray (iebinary_getbytesat (xhr. responsebody, 0, blen). toarray ();
RPG. drawnpc (bytearray ); } Xhr = Null ; } }; Xhr. Open ( 'Get' , URL, True ); Xhr. Send (
Null ); |
References:
New Tricks in xmlhttprequest2
Javascript typed Arrays
Front-end Implementation Scheme for automatic image rotation
Read EXIF data with JavaScript