PageSourceSearch

https://www.xiao-haijing.com/gt4.js

js xiao-haijing.com collected 2026-10-09 03:10:16 UTC 14,792 bytes, 488 lines download raw bytes

1"v4.1.5 Geetest Inc.";
2
3(function (window) {
4    "use strict";
5    if (typeof window === 'undefined') {
6        throw new Error('Geetest requires browser environment');
7    }
8
9var document = window.document;
10var Math = window.Math;
11var head = document.getElementsByTagName("head")[0];
12var TIMEOUT = 10000;
13
14function _Object(obj) {
15    this._obj = obj;
16}
17
18_Object.prototype = {
19    _each: function (process) {
20        var _obj = this._obj;
21        for (var k in _obj) {
22            if (_obj.hasOwnProperty(k)) {
23                process(k, _obj[k]);
24            }
25        }
26        return this;
27    },
28    _extend: function (obj){
29        var self = this;
30        new _Object(obj)._each(function (key, value){
31            self._obj[key] = value;
32        })
33    }
34};
35
36var uuid = function () {
37        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
38            var r = Math.random() * 16 | 0;
39            var v = c === 'x' ? r : (r & 0x3 | 0x8);
40            return v.toString(16);
41        });
42    };
43
44function Config(config) {
45    var self = this;
46    new _Object(config)._each(function (key, value) {
47        self[key] = value;
48    });
49}
50
51Config.prototype = {
52    apiServers: ['gcaptcha4.geetest.com','gcaptcha4.geevisit.com','gcaptcha4.gsensebot.com'],
53    staticServers: ["static.geetest.com",'static.geevisit.com', "dn-staticdown.qbox.me"],
54    protocol: 'http://',
55    typePath: '/load',
56    fallback_config: {
57        bypass: {
58            staticServers: ["static.geetest.com",'static.geevisit.com',"dn-staticdown.qbox.me"],
59            type: 'bypass',
60            bypass: '/v4/bypass.js'
61        }
62    },
63    _get_fallback_config: function () {
64        var self = this;
65        if (isString(self.type)) {
66            return self.fallback_config[self.type];
67        } else {
68            return self.fallback_config.bypass;
69        }
70    },
71    _extend: function (obj) {
72        var self = this;
73        new _Object(obj)._each(function (key, value) {
74            self[key] = value;
75        })
76    }
77};
78var isNumber = function (value) {
79    return (typeof value === 'number');
80};
81var isString = function (value) {
82    return (typeof value === 'string');
83};
84var isBoolean = function (value) {
85    return (typeof value === 'boolean');
86};
87var isObject = function (value) {
88    return (typeof value === 'object' && value !== null);
89};
90var isFunction = function (value) {
91    return (typeof value === 'function');
92};
93var MOBILE = /Mobi/i.test(navigator.userAgent);
94
95var callbacks = {};
96var status = {};
97
98var random = function () {
99    return parseInt(Math.random() * 10000) + (new Date()).valueOf();
100};
101
102// bind 函数polify, 不带new功能的bind
103
104var bind = function(target,context){
105    if(typeof target !== 'function'){
106        return;
107    }
108    var args = Array.prototype.slice.call(arguments,2);
109
110    if(Function.prototype.bind){
111        return target.bind(context, args);
112    }else {
113        return function(){
114            var _args = Array.prototype.slice.call(arguments);
115            return target.apply(context,args.concat(_args));
116        }
117    }
118}
119
120
121
122var toString = Object.prototype.toString;
123
124var _isFunction = function(obj) {
125  return typeof(obj) === 'function';
126};
127var _isObject = function(obj) {
128  return obj === Object(obj);
129};
130var _isArray = function(obj) {
131  return toString.call(obj) == '[object Array]';
132};
133var _isDate = function(obj) {
134  return toString.call(obj) == '[object Date]';
135};
136var _isRegExp = function(obj) {
137  return toString.call(obj) == '[object RegExp]';
138};
139var _isBoolean = function(obj) {
140  return toString.call(obj) == '[object Boolean]';
141};
142
143
144function resolveKey(input){
145  return  input.replace(/(\S)(_([a-zA-Z]))/g, function(match, $1, $2, $3){
146          return $1 + $3.toUpperCase() || "";
147  })
148}
149
150function camelizeKeys(input, convert){
151  if(!_isObject(input) || _isDate(input) || _isRegExp(input) || _isBoolean(input) || _isFunction(input)){
152      return convert ? resolveKey(input) : input;
153  }
154
155  if(_isArray(input)){
156      var temp = [];
157      for(var i = 0; i < input.length; i++){
158          temp.push(camelizeKeys(input[i]));
159      }
160
161  }else {
162      var temp = {};
163      for(var prop in input){
164          if(input.hasOwnProperty(prop)){
165              temp[camelizeKeys(prop, true)] = camelizeKeys(input[prop]);
166          }
167      }
168  }
169  return temp;
170}
171
172var loadScript = function (url, cb, timeout) {
173    var script = document.createElement("script");
174    script.charset = "UTF-8";
175    script.async = true;
176
177    // 对geetest的静态资源添加 crossOrigin
178    if ( /static\.geetest\.com/g.test(url)) {
179        script.crossOrigin = "anonymous";
180    }
181
182    script.onerror = function () {
183        cb(true);
184        // 错误触发了,超时逻辑就不用了
185        loaded = true;
186    };
187    var loaded = false;
188    script.onload = script.onreadystatechange = function () {
189        if (!loaded &&
190            (!script.readyState ||
191            "loaded" === script.readyState ||
192            "complete" === script.readyState)) {
193
194            loaded = true;
195            setTimeout(function () {
196                cb(false);
197            }, 0);
198        }
199    };
200    script.src = url;
201    head.appendChild(script);
202
203    setTimeout(function () {
204        if (!loaded) {
205            script.onerror = script.onload = null;
206            script.remove && script.remove();
207            cb(true);
208        }
209    }, timeout || TIMEOUT);
210};
211
212var normalizeDomain = function (domain) {
213    // special domain: uems.sysu.edu.cn/jwxt/geetest/
214    // return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn
215    return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest
216};
217var normalizePath = function (path) {
218    path = path.replace(/\/+/g, '/');
219    if (path.indexOf('/') !== 0) {
220        path = '/' + path;
221    }
222    return path;
223};
224var normalizeQuery = function (query) {
225    if (!query) {
226        return '';
227    }
228    var q = '?';
229    new _Object(query)._each(function (key, value) {
230        if (isString(value) || isNumber(value) || isBoolean(value)) {
231            q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';
232        }
233    });
234    if (q === '?') {
235        q = '';
236    }
237    return q.replace(/&$/, '');
238};
239var makeURL = function (protocol, domain, path, query) {
240    domain = normalizeDomain(domain);
241
242    var url = normalizePath(path) + normalizeQuery(query);
243    if (domain) {
244        url = protocol + domain + url;
245    }
246
247    return url;
248};
249
250var load = function (config, protocol, domains, path, query, cb, handleCb) {
251    var tryRequest = function (at) {
252
253        // 处理jsonp回调,这里为了保证每个不同jsonp都有唯一的回调函数
254        if(handleCb){
255            var cbName = "geetest_" + random();
256            // 需要与预先定义好cbname参数,删除对象
257            window[cbName] = bind(handleCb, null, cbName);
258            query.callback = cbName;
259        }
260        var url = makeURL(protocol, domains[at], path, query);
261        loadScript(url, function (err) {
262            if (err) {
263                // 超时或者出错的时候 移除回调
264                if(cbName){
265                  try {
266                     window[cbName] = function(){
267                       window[cbName] = null;
268                      }
269                    } catch (e) {}
270                }
271
272                if (at >= domains.length - 1) {
273                    cb(true);
274                    // report gettype error
275                } else {
276                    tryRequest(at + 1);
277                }
278            } else {
279                cb(false);
280            }
281        }, config.timeout);
282    };
283    tryRequest(0);
284};
285
286
287var jsonp = function (domains, path, config, callback) {
288
289    var handleCb = function (cbName, data) {
290
291        // 保证只执行一次,全部超时的情况下不会再触发;
292
293        if (data.status == 'success') {
294            callback(data.data);
295        } else if (!data.status) {
296            callback(data);
297        } else {
298            //接口有返回,但是返回了错误状态,进入报错逻辑
299            callback(data);
300        }
301        window[cbName] = undefined;
302        try {
303            delete window[cbName];
304        } catch (e) {
305        }
306    };
307    load(config, config.protocol, domains, path, {
308        captcha_id: config.captchaId,
309        challenge: config.challenge || uuid(),
310        client_type: MOBILE? 'h5':'web',
311        risk_type: config.riskType,
312        user_info: config.userInfo,
313        call_type: config.callType,
314        lang: config.language? config.language : navigator.appName === 'Netscape' ? navigator.language.toLowerCase() : navigator.userLanguage.toLowerCase()
315    }, function (err) {
316        // 网络问题接口没有返回,直接使用本地验证码,走宕机模式
317        // 这里可以添加用户的逻辑
318            if(err && typeof config.offlineCb === 'function'){
319                // 执行自己的宕机
320                config.offlineCb();
321                return;
322            }
323
324           if(err){
325            callback(config._get_fallback_config());
326           }
327    }, handleCb);
328};
329
330var reportError = function (config, url) {
331    load(config, config.protocol, ['monitor.geetest.com'], '/monitor/send', {
332        time: Date.now().getTime(),
333        captcha_id: config.gt,
334        challenge: config.challenge,
335        exception_url: url,
336        error_code: config.error_code
337    }, function (err) {})
338}
339
340var throwError = function (errorType, config, errObj) {
341    var errors = {
342        networkError: '网络错误',
343        gtTypeError: 'gt字段不是字符串类型'
344    };
345    if (typeof config.onError === 'function') {
346        config.onError({
347            desc: errObj.desc,
348            msg: errObj.msg,
349            code: errObj.code
350        });
351    } else {
352        throw new Error(errors[errorType]);
353    }
354};
355
356var detect = function () {
357    return window.Geetest || document.getElementById("gt_lib");
358};
359
360if (detect()) {
361    status.slide = "loaded";
362}
363var GeetestIsLoad = function (fname) {
364  var GeetestIsLoad = false;
365  var tags = { js: 'script', css: 'link' };
366  var tagname = tags[fname.split('.').pop()];
367  if (tagname !== undefined) {
368    var elts = document.getElementsByTagName(tagname);
369    for (var i in elts) {
370      if ((elts[i].href && elts[i].href.toString().indexOf(fname) > 0)
371              || (elts[i].src && elts[i].src.toString().indexOf(fname) > 0)) {
372        GeetestIsLoad = true;
373      }
374    }
375  }
376  return GeetestIsLoad;
377};
378window.initGeetest4 = function (userConfig,callback) {
379
380    var config = new Config(userConfig);
381    if (userConfig.https) {
382        config.protocol = 'https://';
383    } else if (!userConfig.protocol) {
384        config.protocol = window.location.protocol + '//';
385    }
386
387
388    if (isObject(userConfig.getType)) {
389        config._extend(userConfig.getType);
390    }
391
392    jsonp(config.apiServers , config.typePath, config, function (newConfig) {
393            
394            //错误捕获,第一个load请求可能直接报错
395            var newConfig = camelizeKeys(newConfig);
396
397            if(newConfig.status === 'error'){
398               return throwError('networkError', config, newConfig);
399            }
400
401            var type = newConfig.type;
402            
403            if(config.debug){
404                new _Object(newConfig)._extend(config.debug)
405            }
406            var init = function () {
407                config._extend(newConfig);
408                callback(new window.Geetest4(config));
409            };
410
411            callbacks[type] = callbacks[type] || [];
412
413            var s = status[type] || 'init';
414            if (s === 'init') {
415
416                status[type] = 'loading';
417
418                callbacks[type].push(init);
419
420                if(newConfig.gctPath){
421                    load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){
422                        if(err){
423                            throwError('networkError', config, {
424                                code: '60205',
425                                msg: 'Network failure',
426                                desc: {
427                                    detail: 'gct resource load timeout'
428                                }
429                            });
430                        }
431                    })
432                }
433
434                load(config,  config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers, newConfig.bypass || (newConfig.staticPath + newConfig.js), null, function (err) {
435                    if (err) {
436                        status[type] = 'fail';
437                        throwError('networkError', config, {
438                            code: '60204',
439                            msg: 'Network failure',
440                            desc: {
441                                detail: 'js resource load timeout'
442                            }
443                        });
444                    } else {
445                        status[type] = 'loaded';
446                        var cbs = callbacks[type];
447                        for (var i = 0, len = cbs.length; i < len; i = i + 1) {
448                            var cb = cbs[i];
449                            if (isFunction(cb)) {
450                                cb();
451                            }
452                        }
453                        callbacks[type] = [];
454                    }
455                });
456            } else if (s === "loaded") {
457                // 判断gct是否需要重新加载
458                if(!GeetestIsLoad(newConfig.gctPath)){
459                  load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){
460                      if(err){
461                          throwError('networkError', config, {
462                              code: '60205',
463                              msg: 'Network failure',
464                              desc: {
465                                  detail: 'gct resource load timeout'
466                              }
467                          });
468                      }
469                  })
470                }
471                return  init();
472            } else if (s === "fail") {
473              throwError('networkError', config, {
474                code: '60204',
475                msg: 'Network failure',
476                desc: {
477                    detail: 'js resource load timeout'
478                }
479              });
480            } else if (s === "loading") {
481                callbacks[type].push(init);
482            }
483        });
484
485};
486
487
488})(window);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.