PageSourceSearch

https://www.mexc.com/vendors/gt4.js?v=4.1.1&mexcv=10000

js mexc.com collected 2026-09-24 08:31:32 UTC 13,487 bytes, 460 lines download raw bytes

1"v4.1.1 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'],
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
308    load(config, config.protocol, domains, path, {
309        captcha_id: config.captchaId,
310        challenge: config.challenge || uuid(),
311        client_type: MOBILE? 'h5':'web',
312        risk_type: config.riskType,
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}
363
364window.initGeetest4 = function (userConfig,callback) {
365
366    var config = new Config(userConfig);
367    if (userConfig.https) {
368        config.protocol = 'https://';
369    } else if (!userConfig.protocol) {
370        config.protocol = window.location.protocol + '//';
371    }
372
373
374    if (isObject(userConfig.getType)) {
375        config._extend(userConfig.getType);
376    }
377
378    jsonp(config.apiServers , config.typePath, config, function (newConfig) {
379            
380            //错误捕获,第一个load请求可能直接报错
381            var newConfig = camelizeKeys(newConfig);
382
383            if(newConfig.status === 'error'){
384               return throwError('networkError', config, newConfig);
385            }
386
387            var type = newConfig.type;
388            
389            if(config.debug){
390                new _Object(newConfig)._extend(config.debug)
391            }
392            var init = function () {
393                config._extend(newConfig);
394                callback(new window.Geetest4(config));
395            };
396
397            callbacks[type] = callbacks[type] || [];
398
399            var s = status[type] || 'init';
400            if (s === 'init') {
401
402                status[type] = 'loading';
403
404                callbacks[type].push(init);
405
406                if(newConfig.gctPath){
407                    load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){
408                        if(err){
409                            throwError('networkError', config, {
410                                code: '60205',
411                                msg: 'Network failure',
412                                desc: {
413                                    detail: 'gct resource load timeout'
414                                }
415                            });
416                        }
417                    })
418                }
419
420                load(config,  config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers, newConfig.bypass || (newConfig.staticPath + newConfig.js), null, function (err) {
421                    if (err) {
422                        status[type] = 'fail';
423                        throwError('networkError', config, {
424                            code: '60204',
425                            msg: 'Network failure',
426                            desc: {
427                                detail: 'js resource load timeout'
428                            }
429                        });
430                    } else {
431                        status[type] = 'loaded';
432                        var cbs = callbacks[type];
433                        for (var i = 0, len = cbs.length; i < len; i = i + 1) {
434                            var cb = cbs[i];
435                            if (isFunction(cb)) {
436                                cb();
437                            }
438                        }
439                        callbacks[type] = [];
440                    }
441                });
442            } else if (s === "loaded") {
443                return  init();
444            } else if (s === "fail") {
445              throwError('networkError', config, {
446                code: '60204',
447                msg: 'Network failure',
448                desc: {
449                    detail: 'js resource load timeout'
450                }
451              });
452            } else if (s === "loading") {
453                callbacks[type].push(init);
454            }
455        });
456
457};
458
459
460})(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.