AJAX plugin - SkIvLib

AJAX plugin by Ivan Skvortsov

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

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/31953/209643/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.1.0
  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. var xhttpResponse = [];
  17. function addXHttpResponse( responseText )
  18. {
  19. if( typeof responseText !== 'string' )
  20. return xhttpResponse.push({invalid: true});
  21. xhttpResponse.push({
  22. invalid: false,
  23. text: responseText,
  24. bytes: responseText.length,
  25. Kb: responseText.length/1024.0,
  26. Mb: responseText.length/(1024*1024)
  27. });
  28. }
  29. function queueStatus()
  30. {
  31. return "queueStatus:\n" +
  32. "queue.length = " + queue.length + "\n" +
  33. "in_progress = " + request_in_progress + "\n" +
  34. "cleaned = " + queue_cleaned + "\n" +
  35. "--------------";
  36. }
  37. function requestStatus( request )
  38. {
  39. return "requestStatus:\n" +
  40. "method = " + request.method + "\n" +
  41. "url = " + request.url + "\n" +
  42. "async = " + request.async + "\n" +
  43. "data = " + request.data + "\n" +
  44. //"onload = " + request.onload + "\n" +
  45. "--------------";
  46. }
  47. function createNewObject( obj )
  48. {
  49. if( !obj )
  50. return {};
  51. var new_obj = {}, key, val;
  52. for( key in obj )
  53. {
  54. val = obj[key];
  55. if( Object.prototype.hasOwnProperty.call(obj, key) && val )
  56. new_obj[key] = val;
  57. }
  58. return new_obj;
  59. }
  60. function initXHttpFactory()
  61. {
  62. if( factory && factory.length > 0 )
  63. return;
  64. clog( "initXHttpFactory");
  65. factory = [
  66. function(){ return new XMLHttpRequest();},
  67. function(){ return new ActiveXObject('Msxml3.XMLHTTP');},
  68. function(){ return new ActiveXObject('Msxml2.XMLHTTP.6.0');},
  69. function(){ return new ActiveXObject('Msxml2.XMLHTTP.3.0');},
  70. function(){ return new ActiveXObject('Msxml2.XMLHTTP');},
  71. function(){ return new ActiveXObject('Microsoft.XMLHTTP');},
  72. ];
  73. }
  74. function createXHttp()
  75. {
  76. clog("createXHttp");
  77. initXHttpFactory();
  78. for( let i = 0; i < factory.length; ++i )
  79. {
  80. try{
  81. return factory[i]();
  82. }catch(error){}
  83. }
  84. console.error("[createXHttp] can't create xhttp object");
  85. return null;
  86. }
  87. function getXHttpRequest()
  88. {
  89. clog("getXHttpRequest : queue.length = " + queue.length);
  90. if( !(queue.length > 0) )
  91. return null;
  92. var request = queue[0];
  93. request.method = request.method || 'GET';
  94. if( request.method.toUpperCase() === 'GET' && request.data && request.data !== '' )
  95. {
  96. request.url += '?' + request.data;
  97. request.data = '';
  98. }
  99. request.async = (request.async || true);
  100. request.store = request.store || false;
  101. clog( requestStatus(request) );
  102. return request;
  103. }
  104. function handleXHttpEvent( type, xhttp, request, event )
  105. {
  106. if( queue_cleaned )
  107. return;
  108. clog("handleXHttpEvent : url=" + request.url + ", type=" + type + ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  109. var context, response;
  110. if( request[type] )
  111. {
  112. response = xhttp;
  113. response.lengthComputable = xhttp.lengthComputable || event.lengthComputable || false;
  114. response.loaded = xhttp.loaded || event.loaded || 0;
  115. response.total = xhttp.total || event.total || 0;
  116. response.url = xhttp.responseURL || request.url;
  117. context = request.context || response;
  118. request[type].call( context, response );
  119. if( type === 'onerror' || type === 'onload' )
  120. {
  121. addXHttpResponse( (request.store ? response.responseText : undefined) );
  122. request_in_progress = false;
  123. request.delay = request.delay > 20 ? request.delay : 20;
  124. setTimeout( XHttpRequest, request.delay );
  125. }
  126. }
  127. }
  128. function initXHttpEvents( xhttp, request )
  129. {
  130. var types = [
  131. 'onabort',
  132. 'onerror',
  133. 'onload',
  134. 'onloadend',
  135. 'onloadstart',
  136. 'onprogress',
  137. 'onreadystatechange',
  138. 'ontimeout',
  139. ];
  140. function addXHttpEventListener(type){
  141. if( request[type] )
  142. xhttp[type] = function XHttpEvents(event){handleXHttpEvent(type, xhttp, request, event);};
  143. }
  144. types.forEach( addXHttpEventListener );
  145. clog("initXHttpEvents: ", xhttp);
  146. }
  147. function initXHttp( xhttp, request )
  148. {
  149. initXHttpEvents( xhttp, request );
  150. for( let key in request.headers )
  151. {
  152. xhttp.setRequestHeader( key, request.headers[key] );
  153. }
  154. }
  155. function XHttpRequest()
  156. {
  157. var request, xhttp;
  158. request = getXHttpRequest();
  159. if( request && (request_in_progress === false || request.async === true) && queue.length > 0 )
  160. {
  161. clog("XHttpRequest");
  162. queue.shift();
  163. request_in_progress = true;
  164. xhttp = createXHttp();
  165. initXHttp( xhttp, request );
  166. clog("XHttpRequest : url=" + request.url + ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  167. xhttp.open( request.method, request.url, request.async );
  168. xhttp.send( request.data || null );
  169. }
  170. }
  171. function addXHttpRequest( ...args )
  172. {
  173. var request, url, settings;
  174. switch( args.length )
  175. {
  176. case 0:
  177. return;
  178. case 1:
  179. request = args[0];
  180. clog("request: ", request);
  181. if( request.length )
  182. request.forEach( function(req){ queue.push(req);} );
  183. else
  184. queue.push(request);
  185. break;
  186. case 2:
  187. url = args[0];
  188. settings = args[1];
  189. clog("request: url=" + url + ", settings: ", settings);
  190. if( url.length )
  191. url.forEach( function(u){queue.push(constructXHttpRequest(u, settings));});
  192. else
  193. queue.push( constructXHttpRequest(url, settings) );
  194. break;
  195. default:
  196. return;
  197. }
  198. queue_cleaned = false;
  199. }
  200. function constructXHttpRequest( url, settings )
  201. {
  202. var request = createNewObject(settings);
  203. request.url = url;
  204. return request;
  205. }
  206. function cleanXHttpQueue()
  207. {
  208. xhttpResponse.length = 0;
  209. queue.length = 0;
  210. request_in_progress = false;
  211. queue_cleaned = true;
  212. }
  213. function queueLength()
  214. {
  215. return queue.length;
  216. }
  217. function getXHttpResponse(index)
  218. {
  219. if( !index || index < 0 )
  220. return xhttpResponse;
  221. else if( xhttpResponse.length > 0 )
  222. return xhttpResponse[index];
  223. else
  224. return {text: '', invalid: true, bytes:0, Kb: 0, Mb: 0};
  225. }
  226. window.SkIvLib = window.SkIvLib || {};
  227. // AJAX API
  228. SkIvLib.ajaxResponse = getXHttpResponse;
  229. SkIvLib.ajaxClean = cleanXHttpQueue;
  230. SkIvLib.ajaxLength = queueLength;
  231. SkIvLib.ajaxStatus = queueStatus;
  232. SkIvLib.ajaxAddXHR = addXHttpRequest;
  233. SkIvLib.ajax = function(...args)
  234. {
  235. addXHttpRequest(...args);
  236. console.log("SkIvLib.ajax(): length = " + this.ajaxLength());
  237. XHttpRequest();
  238. };
  239. })();