UNPKG

jquery-ajaxreadystate

Version:
182 lines (162 loc) 5.23 kB
/*! * jquery-ajaxreadystate * @version 1.1.0 * @author Alexander O'Mara * @copyright Copyright (c) 2015 Alexander O'Mara * @license MPL 2.0 <http://mozilla.org/MPL/2.0/> */ /* global jQuery, define, module, require */ (function (factory) { if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if (typeof exports === 'object') { module.exports = factory(require('jquery')); } else { factory(jQuery); } }(function($) { //'use strict';//jQuery cannot use this so neither can we. $.ajaxreadystate = function(url, options) { var ret, xhrOption, xhr, beforeSendOption, ajaxOptions, jqXHR, jqrsc, responseHeaders = null, responseHeadersMap, readyState = 0, eventBinding; //Custom RSC handler. function rsc() { //Get current readyState and set it on the jqXHR object. readyState = jqXHR.readyState = xhr.readyState; //Normalize for browser that do not provide these before receiving data. if (readyState < 2) { jqXHR.status = 0; jqXHR.statusText = ''; jqXHR.responseText = ''; } //Attempt to copy XHR properties onto jqXHR object (can fail in old browsers if AJAX is not complete). try { jqXHR.status = xhr.status || 0; } catch(e) {} try { jqXHR.statusText = xhr.statusText || ''; } catch(e) {} try { jqXHR.responseText = xhr.responseText || ''; } catch(e) {} //Fire the readyState API if set. if (typeof ajaxOptions.readystate === 'function') { ajaxOptions.readystate(jqXHR, readyState); } //Cleanup an bound events. if (eventBinding && readyState === 4) { xhr.removeEventListener(eventBinding, rsc, true); } //Fire the core RSC handler if set and is not the custom handler to prevent infinite recursion (jQuery 2 does not use this). if (jqrsc && jqrsc !== rsc) { jqrsc.apply(xhr, arguments); } } //Try to get all the response headers (can fail in old IE if AJAX is not complete). function tryGetAllResponseHeaders() { var r = null; try { r = xhr.getAllResponseHeaders(); } catch(e) {} return r; } //Find the settings object. ajaxOptions = (typeof url === 'object' ? url : (options || {})); //Patch the beforeSend option. beforeSendOption = ajaxOptions.beforeSend; ajaxOptions.beforeSend = function(jqXHRArg, optionsArg) { //Reset and call the original method if set. ajaxOptions.beforeSend = beforeSendOption; if (beforeSendOption) { beforeSendOption.apply(options, arguments); } //Get the jqXHR object before it is sent. jqXHR = jqXHRArg; //Patch over functions that will not work properly until the entire request completes for browsers that can handle it. jqXHR.getAllResponseHeaders = function() { //Return the response headers caching on first request headers are available on. if (readyState > 1) { responseHeaders = responseHeaders || tryGetAllResponseHeaders(); } return responseHeaders; }; jqXHR.getResponseHeader = function(key) { var match = null, rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg; //Create hash table on first requests headers are available on (based on jQuery core). if (readyState > 1) { responseHeaders = responseHeaders || tryGetAllResponseHeaders(); if (responseHeaders && !responseHeadersMap) { responseHeadersMap = {}; while ((match = rheaders.exec(responseHeaders))) { responseHeadersMap[match[1].toLowerCase()] = match[2]; } } //If the hash table exists, get the value. if (responseHeadersMap) { key = key.toLowerCase(); match = responseHeadersMap.hasOwnProperty(key) ? responseHeadersMap[key] : null; } } return match; }; //Make sure the options object is the same. ajaxOptions = optionsArg; //Patch the XHR option. xhrOption = ajaxOptions.xhr; ajaxOptions.xhr = function() { //Reset and call the original method to create the XHR object and set custom RSC handler. ajaxOptions.xhr = xhrOption; xhr = xhrOption.apply(ajaxOptions, arguments); xhr.onreadystatechange = rsc; //Firefox <= 13 returns XrayWrapper and Firefox <= 3 throws an exception so bind event instead. try { eventBinding = xhr.onreadystatechange !== rsc; } catch(e) { eventBinding = true; } if (eventBinding) { //Check that event can be bound (prevents IE6 error on setting handler to null). if ((eventBinding = xhr.addEventListener)) { xhr.onreadystatechange = null; //Must have capture argument for older implementation. xhr.addEventListener((eventBinding = 'readystatechange'), rsc, true); } } //Return the modified XHR object to the core. return xhr; }; }; //Forward everything to the core AJAX. ret = $.ajax.apply($, arguments); //Do not replace the jQuery RSC handler if using event binding instead. if (!eventBinding) { //Try to copy and replace the core RSC handler (fails in IE6). try { jqrsc = xhr.onreadystatechange; xhr.onreadystatechange = rsc; } catch(e) {} } //Return the AJAX object. return ret; }; }));