UNPKG

9.7 kBJavaScriptView Raw
1"v0.4.7 Geetest Inc.";
2
3(function(window) {
4 "use strict";
5 if (typeof window === "undefined") {
6 throw new Error("Geetest requires browser environment");
7 }
8
9 var document = window.document;
10 var Math = window.Math;
11 var head = document.getElementsByTagName("head")[0];
12
13 function _Object(obj) {
14 this._obj = obj;
15 }
16
17 _Object.prototype = {
18 _each: function(process) {
19 var _obj = this._obj;
20 for (var k in _obj) {
21 if (_obj.hasOwnProperty(k)) {
22 process(k, _obj[k]);
23 }
24 }
25 return this;
26 }
27 };
28
29 function Config(config) {
30 var self = this;
31 new _Object(config)._each(function(key, value) {
32 self[key] = value;
33 });
34 }
35
36 Config.prototype = {
37 api_server: "api.geetest.com",
38 protocol: "http://",
39 typePath: "/gettype.php",
40 fallback_config: {
41 slide: {
42 static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
43 type: "slide",
44 slide: "/static/js/geetest.0.0.0.js"
45 },
46 fullpage: {
47 static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
48 type: "fullpage",
49 fullpage: "/static/js/fullpage.0.0.0.js"
50 }
51 },
52 _get_fallback_config: function() {
53 var self = this;
54 if (isString(self.type)) {
55 return self.fallback_config[self.type];
56 } else if (self.new_captcha) {
57 return self.fallback_config.fullpage;
58 } else {
59 return self.fallback_config.slide;
60 }
61 },
62 _extend: function(obj) {
63 var self = this;
64 new _Object(obj)._each(function(key, value) {
65 self[key] = value;
66 });
67 }
68 };
69 var isNumber = function(value) {
70 return typeof value === "number";
71 };
72 var isString = function(value) {
73 return typeof value === "string";
74 };
75 var isBoolean = function(value) {
76 return typeof value === "boolean";
77 };
78 var isObject = function(value) {
79 return typeof value === "object" && value !== null;
80 };
81 var isFunction = function(value) {
82 return typeof value === "function";
83 };
84 var MOBILE = /Mobi/i.test(navigator.userAgent);
85 var pt = MOBILE ? 3 : 0;
86
87 var callbacks = {};
88 var status = {};
89
90 var nowDate = function() {
91 var date = new Date();
92 var year = date.getFullYear();
93 var month = date.getMonth() + 1;
94 var day = date.getDate();
95 var hours = date.getHours();
96 var minutes = date.getMinutes();
97 var seconds = date.getSeconds();
98
99 if (month >= 1 && month <= 9) {
100 month = "0" + month;
101 }
102 if (day >= 0 && day <= 9) {
103 day = "0" + day;
104 }
105 if (hours >= 0 && hours <= 9) {
106 hours = "0" + hours;
107 }
108 if (minutes >= 0 && minutes <= 9) {
109 minutes = "0" + minutes;
110 }
111 if (seconds >= 0 && seconds <= 9) {
112 seconds = "0" + seconds;
113 }
114 var currentdate =
115 year +
116 "-" +
117 month +
118 "-" +
119 day +
120 " " +
121 hours +
122 ":" +
123 minutes +
124 ":" +
125 seconds;
126 return currentdate;
127 };
128
129 var random = function() {
130 return parseInt(Math.random() * 10000) + new Date().valueOf();
131 };
132
133 var loadScript = function(url, cb) {
134 var script = document.createElement("script");
135 script.charset = "UTF-8";
136 script.async = true;
137
138 script.onerror = function() {
139 cb(true);
140 };
141 var loaded = false;
142 script.onload = script.onreadystatechange = function() {
143 if (
144 !loaded &&
145 (!script.readyState ||
146 "loaded" === script.readyState ||
147 "complete" === script.readyState)
148 ) {
149 loaded = true;
150 setTimeout(function() {
151 cb(false);
152 }, 0);
153 }
154 };
155 script.src = url;
156 head.appendChild(script);
157 };
158
159 var normalizeDomain = function(domain) {
160 // special domain: uems.sysu.edu.cn/jwxt/geetest/
161 // return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn
162 return domain.replace(/^https?:\/\/|\/$/g, ""); // uems.sysu.edu.cn/jwxt/geetest
163 };
164 var normalizePath = function(path) {
165 path = path.replace(/\/+/g, "/");
166 if (path.indexOf("/") !== 0) {
167 path = "/" + path;
168 }
169 return path;
170 };
171 var normalizeQuery = function(query) {
172 if (!query) {
173 return "";
174 }
175 var q = "?";
176 new _Object(query)._each(function(key, value) {
177 if (isString(value) || isNumber(value) || isBoolean(value)) {
178 q = q + encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
179 }
180 });
181 if (q === "?") {
182 q = "";
183 }
184 return q.replace(/&$/, "");
185 };
186 var makeURL = function(protocol, domain, path, query) {
187 domain = normalizeDomain(domain);
188
189 var url = normalizePath(path) + normalizeQuery(query);
190 if (domain) {
191 url = protocol + domain + url;
192 }
193
194 return url;
195 };
196
197 var load = function(config, send, protocol, domains, path, query, cb) {
198 var tryRequest = function(at) {
199 var url = makeURL(protocol, domains[at], path, query);
200 loadScript(url, function(err) {
201 if (err) {
202 if (at >= domains.length - 1) {
203 cb(true);
204 // report gettype error
205 if (send) {
206 config.error_code = 508;
207 var url = protocol + domains[at] + path;
208 reportError(config, url);
209 }
210 } else {
211 tryRequest(at + 1);
212 }
213 } else {
214 cb(false);
215 }
216 });
217 };
218 tryRequest(0);
219 };
220
221 var jsonp = function(domains, path, config, callback) {
222 if (isObject(config.getLib)) {
223 config._extend(config.getLib);
224 callback(config);
225 return;
226 }
227 if (config.offline) {
228 callback(config._get_fallback_config());
229 return;
230 }
231
232 var cb = "geetest_" + random();
233 window[cb] = function(data) {
234 if (data.status == "success") {
235 callback(data.data);
236 } else if (!data.status) {
237 callback(data);
238 } else {
239 callback(config._get_fallback_config());
240 }
241 window[cb] = undefined;
242 try {
243 delete window[cb];
244 } catch (e) {}
245 };
246 load(
247 config,
248 true,
249 config.protocol,
250 domains,
251 path,
252 {
253 gt: config.gt,
254 callback: cb
255 },
256 function(err) {
257 if (err) {
258 callback(config._get_fallback_config());
259 }
260 }
261 );
262 };
263
264 var reportError = function(config, url) {
265 load(
266 config,
267 false,
268 config.protocol,
269 ["monitor.geetest.com"],
270 "/monitor/send",
271 {
272 time: nowDate(),
273 captcha_id: config.gt,
274 challenge: config.challenge,
275 pt: pt,
276 exception_url: url,
277 error_code: config.error_code
278 },
279 function(err) {}
280 );
281 };
282
283 var throwError = function(errorType, config) {
284 var errors = {
285 networkError: "网络错误",
286 gtTypeError: "gt字段不是字符串类型"
287 };
288 if (typeof config.onError === "function") {
289 config.onError(errors[errorType]);
290 } else {
291 throw new Error(errors[errorType]);
292 }
293 };
294
295 var detect = function() {
296 return window.Geetest || document.getElementById("gt_lib");
297 };
298
299 if (detect()) {
300 status.slide = "loaded";
301 }
302
303 window.initGeetest = function(userConfig, callback) {
304 var config = new Config(userConfig);
305
306 if (userConfig.https) {
307 config.protocol = "https://";
308 } else if (!userConfig.protocol) {
309 config.protocol = window.location.protocol + "//";
310 }
311
312 // for KFC
313 if (
314 userConfig.gt === "050cffef4ae57b5d5e529fea9540b0d1" ||
315 userConfig.gt === "3bd38408ae4af923ed36e13819b14d42"
316 ) {
317 config.apiserver = "yumchina.geetest.com/"; // for old js
318 config.api_server = "yumchina.geetest.com";
319 }
320
321 if (isObject(userConfig.getType)) {
322 config._extend(userConfig.getType);
323 }
324 jsonp(
325 [config.api_server || config.apiserver],
326 config.typePath,
327 config,
328 function(newConfig) {
329 var type = newConfig.type;
330 var init = function() {
331 config._extend(newConfig);
332 callback(new window.Geetest(config));
333 };
334
335 callbacks[type] = callbacks[type] || [];
336 var s = status[type] || "init";
337 if (s === "init") {
338 status[type] = "loading";
339
340 callbacks[type].push(init);
341
342 load(
343 config,
344 true,
345 config.protocol,
346 newConfig.static_servers || newConfig.domains,
347 newConfig[type] || newConfig.path,
348 null,
349 function(err) {
350 if (err) {
351 status[type] = "fail";
352 throwError("networkError", config);
353 } else {
354 status[type] = "loaded";
355 var cbs = callbacks[type];
356 for (var i = 0, len = cbs.length; i < len; i = i + 1) {
357 var cb = cbs[i];
358 if (isFunction(cb)) {
359 cb();
360 }
361 }
362 callbacks[type] = [];
363 }
364 }
365 );
366 } else if (s === "loaded") {
367 init();
368 } else if (s === "fail") {
369 throwError("networkError", config);
370 } else if (s === "loading") {
371 callbacks[type].push(init);
372 }
373 }
374 );
375 };
376})(window);