Reading binary data using jQuery Ajax

Posted fit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Reading binary data using jQuery Ajax相关的知识,希望对你有一定的参考价值。

jQuery is an excellent tool to make web development easy and straightforward. It helps while doing DOM manipulation and makes Ajax requests painless across different browsers and platforms. But if you want make an Ajax request, which is giving binary data as a response, you will discover that it does not work for jQuery, at least for now. Changing “dataType” parameter to “text”, does not help, neither changing it to any other jQuery supported Ajax data type.

Problem here is that jQuery still does not support html5 XMLHttpRequest Level 2 binary data type requests – there is even a bug in jQuery bug tracker, which asks for this feature. Although there is a long discussion about this subject on the GitHub, it seems that this feature will not become part of jQuery soon.

 

To find a solution for this problem, we have to modify XMLHttpRequest itself. To read binary data correctly, we have to treat response type as blob data type.

var xhr = new XMLHttpRequest();
xhr.open(‘GET‘, ‘/my/image/name.png‘, true);
xhr.responseType = ‘blob‘;

xhr.onload = function(e) {
  if (this.status == 200) {
    // get binary data as a response
    var blob = this.response;
  }
};

xhr.send();

 But what happens if we have to directly modify received binary data? XHR level 2 also introduces  “ArrayBuffer” response type. An ArrayBuffer is a generic fixed-length container for binary data. They are super handy if you need a generalized buffer of raw data, but the real power is that you can create “views” of the underlying data using JavaScript typed arrays.

var xhr = new XMLHttpRequest();
xhr.open(‘GET‘, ‘/my/image/name.png‘, true);
xhr.responseType = ‘arraybuffer‘;

xhr.onload = function(e) {
  // response is unsigned 8 bit integer
  var responseArray = new Uint8Array(this.response); 
};

xhr.send();

 This request creates an unsigned 8-bit integer array from data buffer. ArrayBuffer is especially useful if you have to read data for WebGL project, WebSocket or Canvas 2D

Binary data ajax tranport for jQuery

Sometimes making complete fallback to XMLHttpRequest is not a good idea, especially if you want to keep jQuery code clean and understandable. To solve this problem, jQuery allows us to create Ajax transports – plugins, which are created to make custom Ajax requests.

Our idea is to make “binary” Ajax transport based on our previous example. This Ajax transport creates new XMLHttpRequest and passes all the received data back to the jQuery.

/**
 *
 * jquery.binarytransport.js
 *
 * @description. jQuery ajax transport for making binary data type requests.
 * @version 1.0 
 * @author Henry Algus <[email protected]>
 *
 */

// use this transport for "binary" data type
$.ajaxTransport("+binary", function(options, originalOptions, jqXHR){
    // check for conditions and support for blob / arraybuffer response type
    if (window.FormData && ((options.dataType && (options.dataType == ‘binary‘)) || (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || (window.Blob && options.data instanceof Blob)))))
    {
        return {
            // create new XMLHttpRequest
            send: function(headers, callback){
		// setup all variables
                var xhr = new XMLHttpRequest(),
		url = options.url,
		type = options.type,
		async = options.async || true,
		// blob or arraybuffer. Default is blob
		dataType = options.responseType || "blob",
		data = options.data || null,
		username = options.username || null,
		password = options.password || null;
					
                xhr.addEventListener(‘load‘, function(){
			var data = {};
			data[options.dataType] = xhr.response;
			// make callback and send data
			callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders());
                });

                xhr.open(type, url, async, username, password);
				
		// setup custom headers
		for (var i in headers ) {
			xhr.setRequestHeader(i, headers[i] );
		}
				
                xhr.responseType = dataType;
                xhr.send(data);
            },
            abort: function(){
                jqXHR.abort();
            }
        };
    }
});

 

For this script to work correctly, processData must be set to false, otherwise jQuery will try to convert received data into string, but fails.

Now it is possible to read binary data using usual jQuery syntax:

$.ajax({
  url: "/my/image/name.png",
  type: "GET",
  dataType: "binary",
  processData: false,
  success: function(result){
	  // do something with binary data
  }
});

 If you want receive ArrayBuffer as response type, you can use responseType parameter while creating Ajax request:

responseType:‘arraybuffer‘

 

How to setup custom headers?

It is possible to set multiple custom headers when you are making the request. To set custom headers, you can use “header” parameter and set its value as an object, which has list of headers:

 

$.ajax({
          url: "image.png",
          type: "GET",
          dataType: ‘binary‘,
          headers:{‘Content-Type‘:‘image/png‘,‘X-Requested-With‘:‘XMLHttpRequest‘},
          processData: false,
          success: function(result){
          }
}); 
 

 

Another options

Asynchronous or synchronous execution

It is possible to change execution type from asynchronous to synchrous when setting parameter “async” to false.

async:false,

Login with user name and password

If your script needs to have authentication during the request, you can use username and password parameters.

username:‘john‘, password:‘smith‘,

Supported browsers

BinaryTransport requires XHR2 responseType, ArrayBuffer and Blob response type support from your browser, otherwise it does not work as expected. Currently most major browsers should work fine.

Firefox: 13.0+ Chrome: 20+ Internet Explorer: 10.0+ Safari: 6.0 Opera: 12.10

Binary transport jQuery plugin is also available in my GitHub repository.

 

以上是关于Reading binary data using jQuery Ajax的主要内容,如果未能解决你的问题,请参考以下文章

Got fatal error 1236 from master when reading data from binary log: 'Could not find first log fi

mysql从库Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could

MySQL案例09:Last_IO_Error: Got fatal error 1236 from master when reading data from binary log

(转)主从同步遇到 Got fatal error 1236 from master when reading data from binary log: 'Could not find fi

允许写入/读取的在线 C++ 编译器

使用jQuery AJAX读取二进制数据