Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 
 
 
 
 

278 rindas
8.7 KiB

  1. /* initGeetest 1.0.0
  2. * 用于加载id对应的验证码库,并支持宕机模式
  3. * 暴露 initGeetest 进行验证码的初始化
  4. * 一般不需要用户进行修改
  5. */
  6. (function (global, factory) {
  7. "use strict";
  8. if (typeof module === "object" && typeof module.exports === "object") {
  9. // CommonJS
  10. module.exports = global.document ?
  11. factory(global, true) :
  12. function (w) {
  13. if (!w.document) {
  14. throw new Error("Geetest requires a window with a document");
  15. }
  16. return factory(w);
  17. };
  18. } else {
  19. factory(global);
  20. }
  21. })(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
  22. "use strict";
  23. if (typeof window === 'undefined') {
  24. throw new Error('Geetest requires browser environment');
  25. }
  26. var document = window.document;
  27. var Math = window.Math;
  28. var head = document.getElementsByTagName("head")[0];
  29. function _Object(obj) {
  30. this._obj = obj;
  31. }
  32. _Object.prototype = {
  33. _each: function (process) {
  34. var _obj = this._obj;
  35. for (var k in _obj) {
  36. if (_obj.hasOwnProperty(k)) {
  37. process(k, _obj[k]);
  38. }
  39. }
  40. return this;
  41. }
  42. };
  43. function Config(config) {
  44. var self = this;
  45. new _Object(config)._each(function (key, value) {
  46. self[key] = value;
  47. });
  48. }
  49. Config.prototype = {
  50. api_server: 'api.geetest.com',
  51. protocol: 'http://',
  52. type_path: '/gettype.php',
  53. fallback_config: {
  54. slide: {
  55. static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
  56. type: 'slide',
  57. slide: '/static/js/geetest.0.0.0.js'
  58. },
  59. fullpage: {
  60. static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
  61. type: 'fullpage',
  62. fullpage: '/static/js/fullpage.0.0.0.js'
  63. }
  64. },
  65. _get_fallback_config: function () {
  66. var self = this;
  67. if (isString(self.type)) {
  68. return self.fallback_config[self.type];
  69. } else if (self.new_captcha) {
  70. return self.fallback_config.fullpage;
  71. } else {
  72. return self.fallback_config.slide;
  73. }
  74. },
  75. _extend: function (obj) {
  76. var self = this;
  77. new _Object(obj)._each(function (key, value) {
  78. self[key] = value;
  79. })
  80. }
  81. };
  82. var isNumber = function (value) {
  83. return (typeof value === 'number');
  84. };
  85. var isString = function (value) {
  86. return (typeof value === 'string');
  87. };
  88. var isBoolean = function (value) {
  89. return (typeof value === 'boolean');
  90. };
  91. var isObject = function (value) {
  92. return (typeof value === 'object' && value !== null);
  93. };
  94. var isFunction = function (value) {
  95. return (typeof value === 'function');
  96. };
  97. var callbacks = {};
  98. var status = {};
  99. var random = function () {
  100. return parseInt(Math.random() * 10000) + (new Date()).valueOf();
  101. };
  102. var loadScript = function (url, cb) {
  103. var script = document.createElement("script");
  104. script.charset = "UTF-8";
  105. script.async = true;
  106. script.onerror = function () {
  107. cb(true);
  108. };
  109. var loaded = false;
  110. script.onload = script.onreadystatechange = function () {
  111. if (!loaded &&
  112. (!script.readyState ||
  113. "loaded" === script.readyState ||
  114. "complete" === script.readyState)) {
  115. loaded = true;
  116. setTimeout(function () {
  117. cb(false);
  118. }, 0);
  119. }
  120. };
  121. script.src = url;
  122. head.appendChild(script);
  123. };
  124. var normalizeDomain = function (domain) {
  125. return domain.replace(/^https?:\/\/|\/$/g, '');
  126. };
  127. var normalizePath = function (path) {
  128. path = path.replace(/\/+/g, '/');
  129. if (path.indexOf('/') !== 0) {
  130. path = '/' + path;
  131. }
  132. return path;
  133. };
  134. var normalizeQuery = function (query) {
  135. if (!query) {
  136. return '';
  137. }
  138. var q = '?';
  139. new _Object(query)._each(function (key, value) {
  140. if (isString(value) || isNumber(value) || isBoolean(value)) {
  141. q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
  142. }
  143. });
  144. if (q === '?') {
  145. q = '';
  146. }
  147. return q.replace(/&$/, '');
  148. };
  149. var makeURL = function (protocol, domain, path, query) {
  150. domain = normalizeDomain(domain);
  151. var url = normalizePath(path) + normalizeQuery(query);
  152. if (domain) {
  153. url = protocol + domain + url;
  154. }
  155. return url;
  156. };
  157. var load = function (protocol, domains, path, query, cb) {
  158. var tryRequest = function (at) {
  159. var url = makeURL(protocol, domains[at], path, query);
  160. loadScript(url, function (err) {
  161. if (err) {
  162. if (at >= domains.length - 1) {
  163. cb(true);
  164. } else {
  165. tryRequest(at + 1);
  166. }
  167. } else {
  168. cb(false);
  169. }
  170. });
  171. };
  172. tryRequest(0);
  173. };
  174. var jsonp = function (domains, path, config, callback) {
  175. if (isObject(config.getLib)) {
  176. config._extend(config.getLib);
  177. callback(config);
  178. return;
  179. }
  180. if (config.offline) {
  181. callback(config._get_fallback_config());
  182. return;
  183. }
  184. var cb = "geetest_" + random();
  185. window[cb] = function (data) {
  186. if (data.status === 'success') {
  187. callback(data.data);
  188. } else if (!data.status) {
  189. callback(data);
  190. } else {
  191. callback(config._get_fallback_config());
  192. }
  193. window[cb] = undefined;
  194. try {
  195. delete window[cb];
  196. } catch (e) {
  197. }
  198. };
  199. load(config.protocol, domains, path, {
  200. gt: config.gt,
  201. callback: cb
  202. }, function (err) {
  203. if (err) {
  204. callback(config._get_fallback_config());
  205. }
  206. });
  207. };
  208. var throwError = function (errorType, config) {
  209. var errors = {
  210. networkError: '网络错误'
  211. };
  212. if (typeof config.onError === 'function') {
  213. config.onError(errors[errorType]);
  214. } else {
  215. throw new Error(errors[errorType]);
  216. }
  217. };
  218. var detect = function () {
  219. return !!window.Geetest;
  220. };
  221. if (detect()) {
  222. status.slide = "loaded";
  223. }
  224. var initGeetest = function (userConfig, callback) {
  225. var config = new Config(userConfig);
  226. if (userConfig.https) {
  227. config.protocol = 'https://';
  228. } else if (!userConfig.protocol) {
  229. config.protocol = window.location.protocol + '//';
  230. }
  231. jsonp([config.api_server || config.apiserver], config.type_path, config, function (newConfig) {
  232. var type = newConfig.type;
  233. var init = function () {
  234. config._extend(newConfig);
  235. callback(new window.Geetest(config));
  236. };
  237. callbacks[type] = callbacks[type] || [];
  238. var s = status[type] || 'init';
  239. if (s === 'init') {
  240. status[type] = 'loading';
  241. callbacks[type].push(init);
  242. load(config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) {
  243. if (err) {
  244. status[type] = 'fail';
  245. throwError('networkError', config);
  246. } else {
  247. status[type] = 'loaded';
  248. var cbs = callbacks[type];
  249. for (var i = 0, len = cbs.length; i < len; i = i + 1) {
  250. var cb = cbs[i];
  251. if (isFunction(cb)) {
  252. cb();
  253. }
  254. }
  255. callbacks[type] = [];
  256. }
  257. });
  258. } else if (s === "loaded") {
  259. init();
  260. } else if (s === "fail") {
  261. throwError('networkError', config);
  262. } else if (s === "loading") {
  263. callbacks[type].push(init);
  264. }
  265. });
  266. };
  267. window.initGeetest = initGeetest;
  268. return initGeetest;
  269. });