Greasy Fork 支持简体中文。

AJAX plugin - SkIvLib

AJAX plugin by Ivan Skvortsov

目前為 2017-08-02 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/31953/209385/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.0
  8. // @grant none
  9. // ==/UserScript==
  10. (function(){
  11. if( !clog )
  12. var clog = console.log;
  13. var factory = [], queue = [], request_in_progress = false, queue_cleaned = true;
  14. function queue_status()
  15. {
  16. return "queue_status:\n" +
  17. "queue.length = " + queue.length + "\n" +
  18. "in_progress = " + request_in_progress + "\n" +
  19. "cleaned = " + queue_cleaned + "\n" +
  20. "--------------";
  21. }
  22. function request_status( request )
  23. {
  24. return "request_status:\n" +
  25. "method = " + request.method + "\n" +
  26. "url = " + request.url + "\n" +
  27. "async = " + request.async + "\n" +
  28. "data = " + request.data + "\n" +
  29. "onload = " + request.onload + "\n" +
  30. "--------------";
  31. }
  32. function createNewObject( obj )
  33. {
  34. var new_obj = {}, key, val;
  35. for( key in obj )
  36. {
  37. val = obj[key];
  38. if( Object.prototype.hasOwnProperty.call(obj, key) && val !== null )
  39. new_obj[key] = val;
  40. }
  41. return new_obj;
  42. }
  43. function initXHttpFactory()
  44. {
  45. if( factory && factory.length > 0 )
  46. return;
  47. clog( "initXHttpFactory : " + (factory ? factory.length : 0) );
  48. factory = [
  49. function(){ return new XMLHttpRequest();},
  50. function(){ return new ActiveXObject('Msxml3.XMLHTTP');},
  51. function(){ return new ActiveXObject('Msxml2.XMLHTTP.6.0');},
  52. function(){ return new ActiveXObject('Msxml2.XMLHTTP.3.0');},
  53. function(){ return new ActiveXObject('Msxml2.XMLHTTP');},
  54. function(){ return new ActiveXObject('Microsoft.XMLHTTP');},
  55. ];
  56. }
  57. function createXHttp()
  58. {
  59. clog("createXHttp");
  60. initXHttpFactory();
  61. for( let i = 0; i < factory.length; ++i )
  62. {
  63. try{
  64. return factory[i]();
  65. }catch(error){}
  66. }
  67. console.error("[createXHttp] can't create xhttp object");
  68. return null;
  69. }
  70. function ObjectToDataString( obj )
  71. {
  72. if( typeof obj === 'object' )
  73. {
  74. var data_str = '', val, key;
  75. for( key in obj )
  76. {
  77. val = obj[key];
  78. if( !Object.prototype.hasOwnProperty.call(obj, key) || !val )
  79. continue;
  80. data_str += key + '=' + val + '&';
  81. }
  82. return data_str.slice(0, -1);
  83. }
  84. else if( typeof obj === 'string' )
  85. return obj;
  86. else
  87. return ( obj ? (obj.toString && obj.toString()) : '' );
  88. }
  89. function getXHttpRequest()
  90. {
  91. clog("getXHttpRequest : queue.length = " + queue.length);
  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. clog( request_status(request) );
  101. return request;
  102. }
  103. function handleXHttpEvent( type, xhttp, request, event )
  104. {
  105. if( queue_cleaned )
  106. return;
  107. clog("handleXHttpEvent : url=" + request.url + ", type=" + type + "" +
  108. ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  109. var context, response;
  110. if( request[type] )
  111. {
  112. response = {
  113. lengthComputable: xhttp.lengthComputable || event.lengthComputable || null,
  114. loaded: xhttp.loaded || event.loaded || 0,
  115. readyState: xhttp.readyState,
  116. responseHeaders: xhttp.responseHeaders ||
  117. (typeof xhttp.getAllResponseHeaders === 'function' ? xhttp.getAllResponseHeaders() : null ) || '',
  118. responseText: xhttp.responseText || xhttp.response,
  119. status: xhttp.status,
  120. statusText: xhttp.statusText,
  121. total: xhttp.total || event.total || 0,
  122. url: xhttp.finalUrl || request.url,
  123. };
  124. context = request.context || response;
  125. request[type].call( context, response );
  126. if( type === 'onerror' || type === 'onload' )
  127. {
  128. request_in_progress = false;
  129. request.delay = request.delay > 20 ? request.delay : 20;
  130. setTimeout( XHttpRequest, request.delay );
  131. }
  132. }
  133. }
  134. function initXHttpEvents( xhttp, request )
  135. {
  136. clog("initXHttpEvents: ", xhttp);
  137. var types = [
  138. 'onerror',
  139. 'onload',
  140. 'onloadend',
  141. 'onloadstart',
  142. 'onprogress',
  143. 'onreadystatechange',
  144. ];
  145. function setXHttpEventListener(type){
  146. xhttp[type] = function(event){ handleXHttpEvent(type, xhttp, request, event); };
  147. }
  148. types.forEach( setXHttpEventListener );
  149. }
  150. function initXHttp( xhttp, request )
  151. {
  152. initXHttpEvents( xhttp, request );
  153. for( let key in request.headers )
  154. {
  155. xhttp.setRequestHeader( key, request.headers[key] );
  156. }
  157. }
  158. function XHttpRequest()
  159. {
  160. clog("---> XHttpRequest <---");
  161. var request, xhttp;
  162. request = getXHttpRequest();
  163. if( request && (request_in_progress === false || request.async === true) && queue.length > 0 )
  164. {
  165. queue.shift();
  166. request_in_progress = true;
  167. xhttp = createXHttp();
  168. initXHttp( xhttp, request );
  169. clog("XHttpRequest : url=" + request.url +
  170. ", readyState=" + xhttp.readyState + ", status=" + xhttp.status );
  171. xhttp.open( request.method, request.url, request.async );
  172. xhttp.send( request.data || null );
  173. }
  174. }
  175. function addXHttpRequest( ...args )
  176. {
  177. var request, url, settings;
  178. switch( args.length )
  179. {
  180. case 0: return;
  181. case 1:
  182. request = args[0];
  183. if( request.length )
  184. request.forEach( function(req){ queue.push(req);} );
  185. else
  186. queue.push(request);
  187. //queue_cleaned = false;
  188. break;
  189. case 2:
  190. url = args[0];
  191. settings = args[1];
  192. if( url.length )
  193. url.forEach( function(u){queue.push(makeXHttpRequest(u, settings));});
  194. else
  195. queue.push( makeXHttpRequest(url, settings) );
  196. //queue_cleaned = false;
  197. break;
  198. default:
  199. return;
  200. //throw new Error("[addXHttpRequest] invalid arguments length: " + args.length );
  201. }
  202. /*
  203. if( request && request.length )
  204. {
  205. request.forEach( function(req){ queue.push(req);} );
  206. }
  207. else if( request )
  208. {
  209. queue.push(request);
  210. }
  211. else if( url && url.length )
  212. {
  213. url.forEach( function(u){queue.push(makeXHttpRequest(u, settings));});
  214. }
  215. else if( url )
  216. {
  217. queue.push( makeXHttpRequest(url, settings) );
  218. }
  219. else
  220. throw new Error("addXHttpRequest] can't add request, args: " + args);
  221. */
  222. queue_cleaned = false;
  223. }
  224. function makeXHttpRequest( url, settings )
  225. {
  226. var request = createNewObject(settings);
  227. request.url = url;
  228. return request;
  229. }
  230. function cleanXHttpQueue()
  231. {
  232. queue.length = 0;
  233. request_in_progress = false;
  234. queue_cleaned = true;
  235. }
  236. function queueLength()
  237. {
  238. return queue.length;
  239. }
  240. // AJAX API
  241. SkIvLib.ajaxClean = cleanXHttpQueue;
  242. SkIvLib.ajaxLength = queueLength;
  243. SkIvLib.ajaxStatus = queue_status;
  244. SkIvLib.ajaxAddXHR = addXHttpRequest;
  245. SkIvLib.ajax = function(...args)
  246. {
  247. addXHttpRequest(...args);
  248. XHttpRequest;
  249. }
  250. })();