ajax.js 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. /**
  2. * @file
  3. * @module UE.ajax
  4. * @since 1.2.6.1
  5. */
  6. /**
  7. * 提供对ajax请求的支持
  8. * @module UE.ajax
  9. */
  10. UE.ajax = (function() {
  11. //创建一个ajaxRequest对象
  12. var fnStr = "XMLHttpRequest()";
  13. try {
  14. new ActiveXObject("Msxml2.XMLHTTP");
  15. fnStr = "ActiveXObject('Msxml2.XMLHTTP')";
  16. } catch (e) {
  17. try {
  18. new ActiveXObject("Microsoft.XMLHTTP");
  19. fnStr = "ActiveXObject('Microsoft.XMLHTTP')";
  20. } catch (e) {}
  21. }
  22. var creatAjaxRequest = new Function("return new " + fnStr);
  23. /**
  24. * 将json参数转化成适合ajax提交的参数列表
  25. * @param json
  26. */
  27. function json2str(json) {
  28. var strArr = [];
  29. for (var i in json) {
  30. //忽略默认的几个参数
  31. if (
  32. i == "method" ||
  33. i == "timeout" ||
  34. i == "async" ||
  35. i == "dataType" ||
  36. i == "callback"
  37. )
  38. continue;
  39. //忽略控制
  40. if (json[i] == undefined || json[i] == null) continue;
  41. //传递过来的对象和函数不在提交之列
  42. if (
  43. !(
  44. (typeof json[i]).toLowerCase() == "function" ||
  45. (typeof json[i]).toLowerCase() == "object"
  46. )
  47. ) {
  48. strArr.push(encodeURIComponent(i) + "=" + encodeURIComponent(json[i]));
  49. } else if (utils.isArray(json[i])) {
  50. //支持传数组内容
  51. for (var j = 0; j < json[i].length; j++) {
  52. strArr.push(
  53. encodeURIComponent(i) + "[]=" + encodeURIComponent(json[i][j])
  54. );
  55. }
  56. }
  57. }
  58. return strArr.join("&");
  59. }
  60. function doAjax(url, ajaxOptions) {
  61. var xhr = creatAjaxRequest(),
  62. //是否超时
  63. timeIsOut = false,
  64. //默认参数
  65. defaultAjaxOptions = {
  66. method: "POST",
  67. timeout: 5000,
  68. async: true,
  69. data: {}, //需要传递对象的话只能覆盖
  70. onsuccess: function() {},
  71. onerror: function() {}
  72. };
  73. if (typeof url === "object") {
  74. ajaxOptions = url;
  75. url = ajaxOptions.url;
  76. }
  77. if (!xhr || !url) return;
  78. var ajaxOpts = ajaxOptions
  79. ? utils.extend(defaultAjaxOptions, ajaxOptions)
  80. : defaultAjaxOptions;
  81. var submitStr = json2str(ajaxOpts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing"
  82. //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串
  83. if (!utils.isEmptyObject(ajaxOpts.data)) {
  84. submitStr += (submitStr ? "&" : "") + json2str(ajaxOpts.data);
  85. }
  86. //超时检测
  87. var timerID = setTimeout(function() {
  88. if (xhr.readyState != 4) {
  89. timeIsOut = true;
  90. xhr.abort();
  91. clearTimeout(timerID);
  92. }
  93. }, ajaxOpts.timeout);
  94. var method = ajaxOpts.method.toUpperCase();
  95. var str =
  96. url +
  97. (url.indexOf("?") == -1 ? "?" : "&") +
  98. (method == "POST" ? "" : submitStr + "&noCache=" + +new Date());
  99. xhr.open(method, str, ajaxOpts.async);
  100. xhr.onreadystatechange = function() {
  101. if (xhr.readyState == 4) {
  102. if (!timeIsOut && xhr.status == 200) {
  103. ajaxOpts.onsuccess(xhr);
  104. } else {
  105. ajaxOpts.onerror(xhr);
  106. }
  107. }
  108. };
  109. if (method == "POST") {
  110. xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  111. xhr.send(submitStr);
  112. } else {
  113. xhr.send(null);
  114. }
  115. }
  116. function doJsonp(url, opts) {
  117. var successhandler = opts.onsuccess || function() {},
  118. scr = document.createElement("SCRIPT"),
  119. options = opts || {},
  120. charset = options["charset"],
  121. callbackField = options["jsonp"] || "callback",
  122. callbackFnName,
  123. timeOut = options["timeOut"] || 0,
  124. timer,
  125. reg = new RegExp("(\\?|&)" + callbackField + "=([^&]*)"),
  126. matches;
  127. if (utils.isFunction(successhandler)) {
  128. callbackFnName =
  129. "bd__editor__" + Math.floor(Math.random() * 2147483648).toString(36);
  130. window[callbackFnName] = getCallBack(0);
  131. } else if (utils.isString(successhandler)) {
  132. callbackFnName = successhandler;
  133. } else {
  134. if ((matches = reg.exec(url))) {
  135. callbackFnName = matches[2];
  136. }
  137. }
  138. url = url.replace(reg, "\x241" + callbackField + "=" + callbackFnName);
  139. if (url.search(reg) < 0) {
  140. url +=
  141. (url.indexOf("?") < 0 ? "?" : "&") +
  142. callbackField +
  143. "=" +
  144. callbackFnName;
  145. }
  146. var queryStr = json2str(opts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing"
  147. //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串
  148. if (!utils.isEmptyObject(opts.data)) {
  149. queryStr += (queryStr ? "&" : "") + json2str(opts.data);
  150. }
  151. if (queryStr) {
  152. url = url.replace(/\?/, "?" + queryStr + "&");
  153. }
  154. scr.onerror = getCallBack(1);
  155. if (timeOut) {
  156. timer = setTimeout(getCallBack(1), timeOut);
  157. }
  158. createScriptTag(scr, url, charset);
  159. function createScriptTag(scr, url, charset) {
  160. scr.setAttribute("type", "text/javascript");
  161. scr.setAttribute("defer", "defer");
  162. charset && scr.setAttribute("charset", charset);
  163. scr.setAttribute("src", url);
  164. document.getElementsByTagName("head")[0].appendChild(scr);
  165. }
  166. function getCallBack(onTimeOut) {
  167. return function() {
  168. try {
  169. if (onTimeOut) {
  170. options.onerror && options.onerror();
  171. } else {
  172. try {
  173. clearTimeout(timer);
  174. successhandler.apply(window, arguments);
  175. } catch (e) {}
  176. }
  177. } catch (exception) {
  178. options.onerror && options.onerror.call(window, exception);
  179. } finally {
  180. options.oncomplete && options.oncomplete.apply(window, arguments);
  181. scr.parentNode && scr.parentNode.removeChild(scr);
  182. window[callbackFnName] = null;
  183. try {
  184. delete window[callbackFnName];
  185. } catch (e) {}
  186. }
  187. };
  188. }
  189. }
  190. return {
  191. /**
  192. * 根据给定的参数项,向指定的url发起一个ajax请求。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求
  193. * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调
  194. * @method request
  195. * @param { URLString } url ajax请求的url地址
  196. * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下:
  197. * @example
  198. * ```javascript
  199. * //向sayhello.php发起一个异步的Ajax GET请求, 请求超时时间为10s, 请求完成后执行相应的回调。
  200. * UE.ajax.requeset( 'sayhello.php', {
  201. *
  202. * //请求方法。可选值: 'GET', 'POST',默认值是'POST'
  203. * method: 'GET',
  204. *
  205. * //超时时间。 默认为5000, 单位是ms
  206. * timeout: 10000,
  207. *
  208. * //是否是异步请求。 true为异步请求, false为同步请求
  209. * async: true,
  210. *
  211. * //请求携带的数据。如果请求为GET请求, data会经过stringify后附加到请求url之后。
  212. * data: {
  213. * name: 'ueditor'
  214. * },
  215. *
  216. * //请求成功后的回调, 该回调接受当前的XMLHttpRequest对象作为参数。
  217. * onsuccess: function ( xhr ) {
  218. * console.log( xhr.responseText );
  219. * },
  220. *
  221. * //请求失败或者超时后的回调。
  222. * onerror: function ( xhr ) {
  223. * alert( 'Ajax请求失败' );
  224. * }
  225. *
  226. * } );
  227. * ```
  228. */
  229. /**
  230. * 根据给定的参数项发起一个ajax请求, 参数项里必须包含一个url地址。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求
  231. * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调。
  232. * @method request
  233. * @warning 如果在参数项里未提供一个key为“url”的地址值,则该请求将直接退出。
  234. * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下:
  235. * @example
  236. * ```javascript
  237. *
  238. * //向sayhello.php发起一个异步的Ajax POST请求, 请求超时时间为5s, 请求完成后不执行任何回调。
  239. * UE.ajax.requeset( 'sayhello.php', {
  240. *
  241. * //请求的地址, 该项是必须的。
  242. * url: 'sayhello.php'
  243. *
  244. * } );
  245. * ```
  246. */
  247. request: function(url, opts) {
  248. if (opts && opts.dataType == "jsonp") {
  249. doJsonp(url, opts);
  250. } else {
  251. doAjax(url, opts);
  252. }
  253. },
  254. getJSONP: function(url, data, fn) {
  255. var opts = {
  256. data: data,
  257. oncomplete: fn
  258. };
  259. doJsonp(url, opts);
  260. }
  261. };
  262. })();