mui.ajax.js 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. /**
  2. * mui ajax
  3. * @param {type} $
  4. * @returns {undefined}
  5. */
  6. (function($, window, undefined) {
  7. var jsonType = 'application/json';
  8. var htmlType = 'text/html';
  9. var rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi;
  10. var scriptTypeRE = /^(?:text|application)\/javascript/i;
  11. var xmlTypeRE = /^(?:text|application)\/xml/i;
  12. var blankRE = /^\s*$/;
  13. $.ajaxSettings = {
  14. type: 'GET',
  15. beforeSend: $.noop,
  16. success: $.noop,
  17. error: $.noop,
  18. complete: $.noop,
  19. context: null,
  20. xhr: function(protocol) {
  21. return new window.XMLHttpRequest();
  22. },
  23. accepts: {
  24. script: 'text/javascript, application/javascript, application/x-javascript',
  25. json: jsonType,
  26. xml: 'application/xml, text/xml',
  27. html: htmlType,
  28. text: 'text/plain'
  29. },
  30. timeout: 0,
  31. processData: true,
  32. cache: true
  33. };
  34. var ajaxBeforeSend = function(xhr, settings) {
  35. var context = settings.context
  36. if(settings.beforeSend.call(context, xhr, settings) === false) {
  37. return false;
  38. }
  39. };
  40. var ajaxSuccess = function(data, xhr, settings) {
  41. settings.success.call(settings.context, data, 'success', xhr);
  42. ajaxComplete('success', xhr, settings);
  43. };
  44. // type: "timeout", "error", "abort", "parsererror"
  45. var ajaxError = function(error, type, xhr, settings) {
  46. settings.error.call(settings.context, xhr, type, error);
  47. ajaxComplete(type, xhr, settings);
  48. };
  49. // status: "success", "notmodified", "error", "timeout", "abort", "parsererror"
  50. var ajaxComplete = function(status, xhr, settings) {
  51. settings.complete.call(settings.context, xhr, status);
  52. };
  53. var serialize = function(params, obj, traditional, scope) {
  54. var type, array = $.isArray(obj),
  55. hash = $.isPlainObject(obj);
  56. $.each(obj, function(key, value) {
  57. type = $.type(value);
  58. if(scope) {
  59. key = traditional ? scope :
  60. scope + '[' + (hash || type === 'object' || type === 'array' ? key : '') + ']';
  61. }
  62. // handle data in serializeArray() format
  63. if(!scope && array) {
  64. params.add(value.name, value.value);
  65. }
  66. // recurse into nested objects
  67. else if(type === "array" || (!traditional && type === "object")) {
  68. serialize(params, value, traditional, key);
  69. } else {
  70. params.add(key, value);
  71. }
  72. });
  73. };
  74. var serializeData = function(options) {
  75. if(options.processData && options.data && typeof options.data !== "string") {
  76. var contentType = options.contentType;
  77. if(!contentType && options.headers) {
  78. contentType = options.headers['Content-Type'];
  79. }
  80. if(contentType && ~contentType.indexOf(jsonType)) { //application/json
  81. options.data = JSON.stringify(options.data);
  82. } else {
  83. options.data = $.param(options.data, options.traditional);
  84. }
  85. }
  86. if(options.data && (!options.type || options.type.toUpperCase() === 'GET')) {
  87. options.url = appendQuery(options.url, options.data);
  88. options.data = undefined;
  89. }
  90. };
  91. var appendQuery = function(url, query) {
  92. if(query === '') {
  93. return url;
  94. }
  95. return(url + '&' + query).replace(/[&?]{1,2}/, '?');
  96. };
  97. var mimeToDataType = function(mime) {
  98. if(mime) {
  99. mime = mime.split(';', 2)[0];
  100. }
  101. return mime && (mime === htmlType ? 'html' :
  102. mime === jsonType ? 'json' :
  103. scriptTypeRE.test(mime) ? 'script' :
  104. xmlTypeRE.test(mime) && 'xml') || 'text';
  105. };
  106. var parseArguments = function(url, data, success, dataType) {
  107. if($.isFunction(data)) {
  108. dataType = success, success = data, data = undefined;
  109. }
  110. if(!$.isFunction(success)) {
  111. dataType = success, success = undefined;
  112. }
  113. return {
  114. url: url,
  115. data: data,
  116. success: success,
  117. dataType: dataType
  118. };
  119. };
  120. $.ajax = function(url, options) {
  121. if(typeof url === "object") {
  122. options = url;
  123. url = undefined;
  124. }
  125. var settings = options || {};
  126. settings.url = url || settings.url;
  127. for(var key in $.ajaxSettings) {
  128. if(settings[key] === undefined) {
  129. settings[key] = $.ajaxSettings[key];
  130. }
  131. }
  132. serializeData(settings);
  133. var dataType = settings.dataType;
  134. if(settings.cache === false || ((!options || options.cache !== true) && ('script' === dataType))) {
  135. settings.url = appendQuery(settings.url, '_=' + $.now());
  136. }
  137. var mime = settings.accepts[dataType && dataType.toLowerCase()];
  138. var headers = {};
  139. var setHeader = function(name, value) {
  140. headers[name.toLowerCase()] = [name, value];
  141. };
  142. var protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol;
  143. var xhr = settings.xhr(settings);
  144. var nativeSetHeader = xhr.setRequestHeader;
  145. var abortTimeout;
  146. setHeader('X-Requested-With', 'XMLHttpRequest');
  147. setHeader('Accept', mime || '*/*');
  148. if(!!(mime = settings.mimeType || mime)) {
  149. if(mime.indexOf(',') > -1) {
  150. mime = mime.split(',', 2)[0];
  151. }
  152. xhr.overrideMimeType && xhr.overrideMimeType(mime);
  153. }
  154. if(settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() !== 'GET')) {
  155. setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded');
  156. }
  157. if(settings.headers) {
  158. for(var name in settings.headers)
  159. setHeader(name, settings.headers[name]);
  160. }
  161. xhr.setRequestHeader = setHeader;
  162. xhr.onreadystatechange = function() {
  163. if(xhr.readyState === 4) {
  164. xhr.onreadystatechange = $.noop;
  165. clearTimeout(abortTimeout);
  166. var result, error = false;
  167. var isLocal = protocol === 'file:';
  168. if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304 || (xhr.status === 0 && isLocal && xhr.responseText)) {
  169. dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type'));
  170. result = xhr.responseText;
  171. try {
  172. // http://perfectionkills.com/global-eval-what-are-the-options/
  173. if(dataType === 'script') {
  174. (1, eval)(result);
  175. } else if(dataType === 'xml') {
  176. result = xhr.responseXML;
  177. } else if(dataType === 'json') {
  178. result = blankRE.test(result) ? null : $.parseJSON(result);
  179. }
  180. } catch(e) {
  181. error = e;
  182. }
  183. if(error) {
  184. ajaxError(error, 'parsererror', xhr, settings);
  185. } else {
  186. ajaxSuccess(result, xhr, settings);
  187. }
  188. } else {
  189. var status = xhr.status ? 'error' : 'abort';
  190. var statusText = xhr.statusText || null;
  191. if(isLocal) {
  192. status = 'error';
  193. statusText = '404';
  194. }
  195. ajaxError(statusText, status, xhr, settings);
  196. }
  197. }
  198. };
  199. if(ajaxBeforeSend(xhr, settings) === false) {
  200. xhr.abort();
  201. ajaxError(null, 'abort', xhr, settings);
  202. return xhr;
  203. }
  204. if(settings.xhrFields) {
  205. for(var name in settings.xhrFields) {
  206. xhr[name] = settings.xhrFields[name];
  207. }
  208. }
  209. var async = 'async' in settings ? settings.async : true;
  210. xhr.open(settings.type.toUpperCase(), settings.url, async, settings.username, settings.password);
  211. for(var name in headers) {
  212. if(headers.hasOwnProperty(name)) {
  213. nativeSetHeader.apply(xhr, headers[name]);
  214. }
  215. }
  216. if(settings.timeout > 0) {
  217. abortTimeout = setTimeout(function() {
  218. xhr.onreadystatechange = $.noop;
  219. xhr.abort();
  220. ajaxError(null, 'timeout', xhr, settings);
  221. }, settings.timeout);
  222. }
  223. xhr.send(settings.data ? settings.data : null);
  224. return xhr;
  225. };
  226. $.param = function(obj, traditional) {
  227. var params = [];
  228. params.add = function(k, v) {
  229. this.push(encodeURIComponent(k) + '=' + encodeURIComponent(v));
  230. };
  231. serialize(params, obj, traditional);
  232. return params.join('&').replace(/%20/g, '+');
  233. };
  234. $.get = function( /* url, data, success, dataType */ ) {
  235. return $.ajax(parseArguments.apply(null, arguments));
  236. };
  237. $.post = function( /* url, data, success, dataType */ ) {
  238. var options = parseArguments.apply(null, arguments);
  239. options.type = 'POST';
  240. return $.ajax(options);
  241. };
  242. $.getJSON = function( /* url, data, success */ ) {
  243. var options = parseArguments.apply(null, arguments);
  244. options.dataType = 'json';
  245. return $.ajax(options);
  246. };
  247. $.fn.load = function(url, data, success) {
  248. if(!this.length)
  249. return this;
  250. var self = this,
  251. parts = url.split(/\s/),
  252. selector,
  253. options = parseArguments(url, data, success),
  254. callback = options.success;
  255. if(parts.length > 1)
  256. options.url = parts[0], selector = parts[1];
  257. options.success = function(response) {
  258. if(selector) {
  259. var div = document.createElement('div');
  260. div.innerHTML = response.replace(rscript, "");
  261. var selectorDiv = document.createElement('div');
  262. var childs = div.querySelectorAll(selector);
  263. if(childs && childs.length > 0) {
  264. for(var i = 0, len = childs.length; i < len; i++) {
  265. selectorDiv.appendChild(childs[i]);
  266. }
  267. }
  268. self[0].innerHTML = selectorDiv.innerHTML;
  269. } else {
  270. self[0].innerHTML = response;
  271. }
  272. callback && callback.apply(self, arguments);
  273. };
  274. $.ajax(options);
  275. return this;
  276. };
  277. })(mui, window);