AJAX plugin - SkIvLib

AJAX plugin by Ivan Skvortsov

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

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/31953/209647/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.1
  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 = (typeof request.async !== 'boolean' ? true : request.async );
  100. request.store = (typeof request.store !== 'boolean' ? false: request.store );
  101. clog( requestStatus(request) );
  102. return request;
  103. }
  104. function handleXHttpEvent( type, xhttp, request, event )
  105. {
  106. clog("handleXHttpEvent : url=" + request.url + ", type=" + type + ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  107. var context, response;
  108. if( request[type] )
  109. {
  110. response = xhttp;
  111. response.lengthComputable = xhttp.lengthComputable || event.lengthComputable || false;
  112. response.loaded = xhttp.loaded || event.loaded || 0;
  113. response.total = xhttp.total || event.total || 0;
  114. response.url = xhttp.responseURL || request.url;
  115. context = request.context || response;
  116. request[type].call( context, response );
  117. if( type === 'onerror' || type === 'onload' )
  118. {
  119. addXHttpResponse( (request.store ? response.responseText : undefined) );
  120. request_in_progress = false;
  121. request.delay = request.delay > 20 ? request.delay : 20;
  122. setTimeout( XHttpRequest, request.delay );
  123. }
  124. }
  125. }
  126. function initXHttpEvents( xhttp, request )
  127. {
  128. var types = [
  129. 'onabort',
  130. 'onerror',
  131. 'onload',
  132. 'onloadend',
  133. 'onloadstart',
  134. 'onprogress',
  135. 'onreadystatechange',
  136. 'ontimeout',
  137. ];
  138. function addXHttpEventListener(type){
  139. if( request[type] )
  140. xhttp[type] = function XHttpEvents(event){handleXHttpEvent(type, xhttp, request, event);};
  141. }
  142. types.forEach( addXHttpEventListener );
  143. clog("initXHttpEvents: ", xhttp);
  144. }
  145. function initXHttp( xhttp, request )
  146. {
  147. initXHttpEvents( xhttp, request );
  148. for( let key in request.headers )
  149. {
  150. xhttp.setRequestHeader( key, request.headers[key] );
  151. }
  152. }
  153. function XHttpRequest()
  154. {
  155. var request, xhttp;
  156. request = getXHttpRequest();
  157. if( request && (request_in_progress === false || request.async === true) && queue.length > 0 )
  158. {
  159. clog("XHttpRequest");
  160. queue.shift();
  161. request_in_progress = true;
  162. xhttp = createXHttp();
  163. initXHttp( xhttp, request );
  164. clog("XHttpRequest : url=" + request.url + ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  165. xhttp.open( request.method, request.url, request.async );
  166. xhttp.send( request.data || null );
  167. }
  168. }
  169. function addXHttpRequest( ...args )
  170. {
  171. var request, url, settings;
  172. switch( args.length )
  173. {
  174. case 0:
  175. return;
  176. case 1:
  177. request = args[0];
  178. clog("request: ", request);
  179. if( request.length )
  180. request.forEach( function(req){ queue.push(req);} );
  181. else
  182. queue.push(request);
  183. break;
  184. case 2:
  185. url = args[0];
  186. settings = args[1];
  187. clog("request: url=" + url + ", settings: ", settings);
  188. if( url.length )
  189. url.forEach( function(u){queue.push(constructXHttpRequest(u, settings));});
  190. else
  191. queue.push( constructXHttpRequest(url, settings) );
  192. break;
  193. default:
  194. return;
  195. }
  196. queue_cleaned = false;
  197. }
  198. function constructXHttpRequest( url, settings )
  199. {
  200. var request = createNewObject(settings);
  201. request.url = url;
  202. return request;
  203. }
  204. function cleanXHttpQueue()
  205. {
  206. xhttpResponse.length = 0;
  207. queue.length = 0;
  208. request_in_progress = false;
  209. queue_cleaned = true;
  210. }
  211. function queueLength()
  212. {
  213. return queue.length;
  214. }
  215. function getXHttpResponse(index)
  216. {
  217. if( !index || index < 0 )
  218. return xhttpResponse;
  219. else if( xhttpResponse.length > 0 )
  220. return xhttpResponse[index];
  221. else
  222. return {text: '', invalid: true, bytes:0, Kb: 0, Mb: 0};
  223. }
  224. window.SkIvLib = window.SkIvLib || {};
  225. // AJAX API
  226. SkIvLib.ajaxResponse = getXHttpResponse;
  227. SkIvLib.ajaxClean = cleanXHttpQueue;
  228. SkIvLib.ajaxLength = queueLength;
  229. SkIvLib.ajaxStatus = queueStatus;
  230. SkIvLib.ajaxAddXHR = addXHttpRequest;
  231. SkIvLib.ajax = function(...args)
  232. {
  233. xhttpResponse.length = 0;
  234. addXHttpRequest(...args);
  235. console.log("SkIvLib.ajax(): length = " + this.ajaxLength());
  236. XHttpRequest();
  237. };
  238. })();