AJAX plugin - SkIvLib

AJAX plugin by Ivan Skvortsov

当前为 2017-08-03 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/31953/209640/AJAX%20plugin%20-%20SkIvLib.js

  1. // ==UserScript==
  2. // @name AJAX plugin - SkIvLib
  3. // @description AJAX plugin by Ivan Skvortsov
  4. // @description:ru AJAX плагин от Ivan Skvortsov
  5. // @include *://*
  6. // @author Ivan Skvortsov
  7. // @version 1.0.3
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. (function(){
  12. var clog;// = function(){};
  13. if( !clog )
  14. clog = console.log;
  15. var factory = [], queue = [], request_in_progress = false, queue_cleaned = true;
  16. function queueStatus()
  17. {
  18. return "queueStatus:\n" +
  19. "queue.length = " + queue.length + "\n" +
  20. "in_progress = " + request_in_progress + "\n" +
  21. "cleaned = " + queue_cleaned + "\n" +
  22. "--------------";
  23. }
  24. function requestStatus( request )
  25. {
  26. return "requestStatus:\n" +
  27. "method = " + request.method + "\n" +
  28. "url = " + request.url + "\n" +
  29. "async = " + request.async + "\n" +
  30. "data = " + request.data + "\n" +
  31. //"onload = " + request.onload + "\n" +
  32. "--------------";
  33. }
  34. function createNewObject( obj )
  35. {
  36. if( !obj )
  37. return {};
  38. var new_obj = {}, key, val;
  39. for( key in obj )
  40. {
  41. val = obj[key];
  42. if( Object.prototype.hasOwnProperty.call(obj, key) && val )
  43. new_obj[key] = val;
  44. }
  45. return new_obj;
  46. }
  47. function initXHttpFactory()
  48. {
  49. if( factory && factory.length > 0 )
  50. return;
  51. clog( "initXHttpFactory");
  52. factory = [
  53. function(){ return new XMLHttpRequest();},
  54. function(){ return new ActiveXObject('Msxml3.XMLHTTP');},
  55. function(){ return new ActiveXObject('Msxml2.XMLHTTP.6.0');},
  56. function(){ return new ActiveXObject('Msxml2.XMLHTTP.3.0');},
  57. function(){ return new ActiveXObject('Msxml2.XMLHTTP');},
  58. function(){ return new ActiveXObject('Microsoft.XMLHTTP');},
  59. ];
  60. }
  61. function createXHttp()
  62. {
  63. clog("createXHttp");
  64. initXHttpFactory();
  65. for( let i = 0; i < factory.length; ++i )
  66. {
  67. try{
  68. return factory[i]();
  69. }catch(error){}
  70. }
  71. console.error("[createXHttp] can't create xhttp object");
  72. return null;
  73. }
  74. function getXHttpRequest()
  75. {
  76. //clog("getXHttpRequest : queue.length = " + queue.length);
  77. if( !(queue.length > 0) )
  78. return null;
  79. var request = queue[0];
  80. request.method = request.method || 'GET';
  81. if( request.method.toUpperCase() === 'GET' && request.data && request.data !== '' )
  82. {
  83. request.url += '?' + request.data;
  84. request.data = '';
  85. }
  86. request.async = (request.async || true);
  87. //clog( requestStatus(request) );
  88. return request;
  89. }
  90. function handleXHttpEvent( type, xhttp, request, event )
  91. {
  92. if( queue_cleaned )
  93. return;
  94. //clog("handleXHttpEvent : url=" + request.url + ", type=" + type + ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  95. var context, response;
  96. if( request[type] )
  97. {
  98. response = xhttp;
  99. response.lengthComputable = xhttp.lengthComputable || event.lengthComputable || false;
  100. response.loaded = xhttp.loaded || event.loaded || 0;
  101. response.total = xhttp.total || event.total || 0;
  102. response.url = xhttp.responseURL || request.url;
  103. context = request.context || response;
  104. request[type].call( context, response );
  105. if( type === 'onerror' || type === 'onload' )
  106. {
  107. request_in_progress = false;
  108. request.delay = request.delay > 20 ? request.delay : 20;
  109. setTimeout( XHttpRequest, request.delay );
  110. }
  111. }
  112. }
  113. function initXHttpEvents( xhttp, request )
  114. {
  115. //clog("initXHttpEvents: ", xhttp);
  116. var types = [
  117. 'onabort',
  118. 'onerror',
  119. 'onload',
  120. 'onloadend',
  121. 'onloadstart',
  122. 'onprogress',
  123. 'onreadystatechange',
  124. 'ontimeout',
  125. ];
  126. function addXHttpEventListener(type){
  127. if( request[type] )
  128. xhttp[type] = function XHttpEvents(event){handleXHttpEvent(type, xhttp, request, event);};
  129. }
  130. types.forEach( addXHttpEventListener );
  131. }
  132. function initXHttp( xhttp, request )
  133. {
  134. initXHttpEvents( xhttp, request );
  135. for( let key in request.headers )
  136. {
  137. xhttp.setRequestHeader( key, request.headers[key] );
  138. }
  139. }
  140. function XHttpRequest()
  141. {
  142. clog("---> XHttpRequest <---");
  143. var request, xhttp;
  144. request = getXHttpRequest();
  145. if( request && (request_in_progress === false || request.async === true) && queue.length > 0 )
  146. {
  147. queue.shift();
  148. request_in_progress = true;
  149. xhttp = createXHttp();
  150. initXHttp( xhttp, request );
  151. //clog("XHttpRequest : url=" + request.url + ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  152. xhttp.open( request.method, request.url, request.async );
  153. xhttp.send( request.data || null );
  154. }
  155. }
  156. function addXHttpRequest( ...args )
  157. {
  158. var request, url, settings;
  159. switch( args.length )
  160. {
  161. case 0:
  162. return;
  163. case 1:
  164. request = args[0];
  165. clog("request: ", request);
  166. if( request.length )
  167. request.forEach( function(req){ queue.push(req);} );
  168. else
  169. queue.push(request);
  170. break;
  171. case 2:
  172. url = args[0];
  173. settings = args[1];
  174. clog("request: url=" + url + ", settings: ", settings);
  175. if( url.length )
  176. url.forEach( function(u){queue.push(constructXHttpRequest(u, settings));});
  177. else
  178. queue.push( constructXHttpRequest(url, settings) );
  179. break;
  180. default:
  181. return;
  182. }
  183. queue_cleaned = false;
  184. }
  185. function constructXHttpRequest( url, settings )
  186. {
  187. var request = createNewObject(settings);
  188. request.url = url;
  189. return request;
  190. }
  191. function cleanXHttpQueue()
  192. {
  193. queue.length = 0;
  194. request_in_progress = false;
  195. queue_cleaned = true;
  196. }
  197. function queueLength()
  198. {
  199. return queue.length;
  200. }
  201. window.SkIvLib = window.SkIvLib || {};
  202. // AJAX API
  203. SkIvLib.ajaxClean = cleanXHttpQueue;
  204. SkIvLib.ajaxLength = queueLength;
  205. SkIvLib.ajaxStatus = queueStatus;
  206. SkIvLib.ajaxAddXHR = addXHttpRequest;
  207. SkIvLib.ajax = function(...args)
  208. {
  209. clog("SkIvLib.ajax");
  210. addXHttpRequest(...args);
  211. XHttpRequest();
  212. }
  213. })();