Skip to content

Instantly share code, notes, and snippets.

@SaneMethod
Last active March 14, 2022 17:57
Show Gist options
  • Save SaneMethod/7548768 to your computer and use it in GitHub Desktop.
Save SaneMethod/7548768 to your computer and use it in GitHub Desktop.
Ajax transports to allow the sending/receiving of blobs and array buffers via the familiar jquery ajax function.To send, set data to the blob or arraybuffer to be sent, and add 'processData:false' to the ajax options.To receive, specify the 'dataType' as blob or arraybuffer in the ajax options.
(function($){
/**
* Register ajax transports for blob send/recieve and array buffer send/receive via XMLHttpRequest Level 2
* within the comfortable framework of the jquery ajax request, with full support for promises.
*
* Notice the +* in the dataType string? The + indicates we want this transport to be prepended to the list
* of potential transports (so it gets first dibs if the request passes the conditions within to provide the
* ajax transport, preventing the standard transport from hogging the request), and the * indicates that
* potentially any request with any dataType might want to use the transports provided herein.
*
* Remember to specify 'processData:false' in the ajax options when attempting to send a blob or arraybuffer -
* otherwise jquery will try (and fail) to convert the blob or buffer into a query string.
*
* This revision now includes sending headers, resolves the stack overflow in abort(), and sets the status text
* into the response if the request is unsuccessful.
*/
$.ajaxTransport("+*", function(options, originalOptions, jqXHR){
// Test for the conditions that mean we can/want to send/receive blobs or arraybuffers - we need XMLHttpRequest
// level 2 (so feature-detect against window.FormData), feature detect against window.Blob or window.ArrayBuffer,
// and then check to see if the dataType is blob/arraybuffer or the data itself is a Blob/ArrayBuffer
if (window.FormData && ((options.dataType && (options.dataType == 'blob' || options.dataType == 'arraybuffer'))
|| (options.data && ((window.Blob && options.data instanceof Blob)
|| (window.ArrayBuffer && options.data instanceof ArrayBuffer)))
))
{
var xhr;
return {
/**
* Return a transport capable of sending and/or receiving blobs - in this case, we instantiate
* a new XMLHttpRequest and use it to actually perform the request, and funnel the result back
* into the jquery complete callback (such as the success function, done blocks, etc.)
*
* @param headers
* @param completeCallback
*/
send: function(headers, completeCallback){
var url = options.url || window.location.href,
type = options.type || 'GET',
dataType = options.dataType || 'text',
data = options.data || null,
async = options.async || true;
xhr = new XMLHttpRequest();
xhr.addEventListener('load', function(){
var res = {},
success = xhr.status >= 200 && xhr.status < 300 || xhr.status === 304;
if (success){
res[dataType] = xhr.response;
} else {
res.text = xhr.statusText;
}
completeCallback(xhr.status, xhr.statusText, res, xhr.getAllResponseHeaders());
});
xhr.open(type, url, async);
xhr.responseType = dataType;
for (var key in headers){
if (headers.hasOwnProperty(key)){
xhr.setRequestHeader(key, headers[key]);
}
}
xhr.send(data);
},
abort: function(){
if (xhr){
xhr.abort();
}
}
};
}
});
})(jQuery);
@miguelcobain
Copy link

Hi.
Thanks a lot for the code!

Does this send headers too? I don't see you using them anywhere.

Thanks.

@aaronk6
Copy link

aaronk6 commented Jul 18, 2014

Hey @miguelcobain,

Does this send headers too? I don't see you using them anywhere.

No, it doesn’t. I’ve created a fork that does: https://gist.github.com/aaronk6/bff7cc600d863d31a7bf

Cheers!

@leandro9119
Copy link

Thanks a lot for the code!

@SaneMethod
Copy link
Author

Does this send headers too?

It does now.

@beiersi
Copy link

beiersi commented Jan 9, 2016

👍

@kazaff
Copy link

kazaff commented Jul 20, 2016

cool!

i try to use jQuery.ajaxSetup() to solve this issue, but fail.

thank you for your code~

@Lin07ux
Copy link

Lin07ux commented Jul 21, 2016

Line 42:async = options.async || true;

async is true always without false, even though I set options.async = false.

@mlissner
Copy link

This is wonderful. One suggestion: Add a link back to this page to the headnotes in the JS. That'll make it possible for folks to keep track of where they got it from if it ever had a bug or whatever.

@caldus85
Copy link

Thanks so much for this! This solved a problem I was having where I wanted to download a PDF using the $.ajax method (POST request) and then add the resulting ArrayBuffer to a zip file using the JSZip library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment