PageSourceSearch

https://qqwin.ai/libs/rc/[email protected]/gt.js

js qqwin.ai collected 2026-10-05 13:33:02 UTC 14,326 bytes, 537 lines download raw bytes

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