| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 | "v1.0.0 Captcha4 Inc.";(function (window) {    "use strict";    if (typeof window === 'undefined') {        throw new Error('Captcha4 requires browser environment');    }var document = window.document;var Math = window.Math;var head = document.getElementsByTagName("head")[0];var TIMEOUT = 10000;function _Object(obj) {    this._obj = obj;}_Object.prototype = {    _each: function (process) {        var _obj = this._obj;        for (var k in _obj) {            if (_obj.hasOwnProperty(k)) {                process(k, _obj[k]);            }        }        return this;    },    _extend: function (obj){        var self = this;        new _Object(obj)._each(function (key, value){            self._obj[key] = value;        })    }};var uuid = function () {        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {            var r = Math.random() * 16 | 0;            var v = c === 'x' ? r : (r & 0x3 | 0x8);            return v.toString(16);        });    };function Config(config) {    var self = this;    new _Object(config)._each(function (key, value) {        self[key] = value;    });}Config.prototype = {    apiServers: ['captcha.alicaptcha.com','captchabak.alicaptcha.com'],    staticServers: ["static.alicaptcha.com"],    protocol: 'http://',    typePath: '/load',    fallback_config: {        bypass: {            staticServers: ["static.alicaptcha.com"],            type: 'bypass',            bypass: '/v4/alibypass.js'        }    },    _get_fallback_config: function () {        var self = this;        if (isString(self.type)) {            return self.fallback_config[self.type];        } else {            return self.fallback_config.bypass;        }    },    _extend: function (obj) {        var self = this;        new _Object(obj)._each(function (key, value) {            self[key] = value;        })    }};var isNumber = function (value) {    return (typeof value === 'number');};var isString = function (value) {    return (typeof value === 'string');};var isBoolean = function (value) {    return (typeof value === 'boolean');};var isObject = function (value) {    return (typeof value === 'object' && value !== null);};var isFunction = function (value) {    return (typeof value === 'function');};var MOBILE = /Mobi/i.test(navigator.userAgent);var callbacks = {};var status = {};var random = function () {    return parseInt(Math.random() * 10000) + (new Date()).valueOf();};// bind 函数polify, 不带new功能的bindvar bind = function(target,context){    if(typeof target !== 'function'){        return;    }    var args = Array.prototype.slice.call(arguments,2);    if(Function.prototype.bind){        return target.bind(context, args);    }else {        return function(){            var _args = Array.prototype.slice.call(arguments);            return target.apply(context,args.concat(_args));        }    }}var toString = Object.prototype.toString;var _isFunction = function(obj) {  return typeof(obj) === 'function';};var _isObject = function(obj) {  return obj === Object(obj);};var _isArray = function(obj) {  return toString.call(obj) == '[object Array]';};var _isDate = function(obj) {  return toString.call(obj) == '[object Date]';};var _isRegExp = function(obj) {  return toString.call(obj) == '[object RegExp]';};var _isBoolean = function(obj) {  return toString.call(obj) == '[object Boolean]';};function resolveKey(input){  return  input.replace(/(\S)(_([a-zA-Z]))/g, function(match, $1, $2, $3){          return $1 + $3.toUpperCase() || "";  })}function camelizeKeys(input, convert){  if(!_isObject(input) || _isDate(input) || _isRegExp(input) || _isBoolean(input) || _isFunction(input)){      return convert ? resolveKey(input) : input;  }  if(_isArray(input)){      var temp = [];      for(var i = 0; i < input.length; i++){          temp.push(camelizeKeys(input[i]));      }  }else {      var temp = {};      for(var prop in input){          if(input.hasOwnProperty(prop)){              temp[camelizeKeys(prop, true)] = camelizeKeys(input[prop]);          }      }  }  return temp;}var loadScript = function (url, cb, timeout) {    var script = document.createElement("script");    script.charset = "UTF-8";    script.async = true;    // 对geetest的静态资源添加 crossOrigin    if ( /static\.geetest\.com/g.test(url)) {        script.crossOrigin = "anonymous";    }    script.onerror = function () {        cb(true);        // 错误触发了,超时逻辑就不用了        loaded = true;    };    var loaded = false;    script.onload = script.onreadystatechange = function () {        if (!loaded &&            (!script.readyState ||            "loaded" === script.readyState ||            "complete" === script.readyState)) {            loaded = true;            setTimeout(function () {                cb(false);            }, 0);        }    };    script.src = url;    head.appendChild(script);    setTimeout(function () {        if (!loaded) {            script.onerror = script.onload = null;            script.remove && script.remove();            cb(true);        }    }, timeout || TIMEOUT);};var normalizeDomain = function (domain) {    // special domain: uems.sysu.edu.cn/jwxt/geetest/    // return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn    return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest};var normalizePath = function (path) {    path = path && path.replace(/\/+/g, '/');    if (path.indexOf('/') !== 0) {        path = '/' + path;    }    return path;};var normalizeQuery = function (query) {    if (!query) {        return '';    }    var q = '?';    new _Object(query)._each(function (key, value) {        if (isString(value) || isNumber(value) || isBoolean(value)) {            q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&';        }    });    if (q === '?') {        q = '';    }    return q.replace(/&$/, '');};var makeURL = function (protocol, domain, path, query) {    domain = normalizeDomain(domain);    var url = normalizePath(path) + normalizeQuery(query);    if (domain) {        url = protocol + domain + url;    }    return url;};var load = function (config, protocol, domains, path, query, cb, handleCb) {    var tryRequest = function (at) {        // 处理jsonp回调,这里为了保证每个不同jsonp都有唯一的回调函数        if(handleCb){            var cbName = "captcha4_" + random();            // 需要与预先定义好cbname参数,删除对象            window[cbName] = bind(handleCb, null, cbName);            query.callback = cbName;        }        var url = makeURL(protocol, domains[at], path, query);        loadScript(url, function (err) {            if (err) {                // 超时或者出错的时候 移除回调                if(cbName){                  try {                     window[cbName] = function(){                       window[cbName] = null;                      }                    } catch (e) {}                }                if (at >= domains.length - 1) {                    cb(true);                    // report gettype error                } else {                    tryRequest(at + 1);                }            } else {                cb(false);            }        }, config.timeout);    };    tryRequest(0);};var jsonp = function (domains, path, config, callback) {    var handleCb = function (cbName, data) {        // 保证只执行一次,全部超时的情况下不会再触发;        if (data.status == 'success') {            callback(data.data);        } else if (!data.status) {            callback(data);        } else {            //接口有返回,但是返回了错误状态,进入报错逻辑            callback(data);        }        window[cbName] = undefined;        try {            delete window[cbName];        } catch (e) {        }    };    load(config, config.protocol, domains, path, {        callback: '',        captcha_id: config.captchaId,        challenge: config.challenge || uuid(),        client_type: MOBILE? 'h5':'web',        risk_type: config.riskType,        user_info: config.userInfo,        call_type: config.callType,        lang: config.language? config.language : navigator.appName === 'Netscape' ? navigator.language.toLowerCase() : navigator.userLanguage.toLowerCase()    }, function (err) {        // 网络问题接口没有返回,直接使用本地验证码,走宕机模式        // 这里可以添加用户的逻辑            if(err && typeof config.offlineCb === 'function'){                // 执行自己的宕机                config.offlineCb();                return;            }           if(err){            callback(config._get_fallback_config());           }    }, handleCb);};var reportError = function (config, url) {    load(config, config.protocol, ['monitor.geetest.com'], '/monitor/send', {        time: Date.now().getTime(),        captcha_id: config.gt,        challenge: config.challenge,        exception_url: url,        error_code: config.error_code    }, function (err) {})}var throwError = function (errorType, config, errObj) {    var errors = {        networkError: '网络错误',        gtTypeError: 'gt字段不是字符串类型'    };    if (typeof config.onError === 'function') {        config.onError({            desc: errObj.desc,            msg: errObj.msg,            code: errObj.code        });    } else {        throw new Error(errors[errorType]);    }};var detect = function () {    return window.Captcha4 || document.getElementById("gt_lib");};if (detect()) {    status.slide = "loaded";}var Captcha4IsLoad = function (fname) {  var Captcha4IsLoad = false;  var tags = { js: 'script', css: 'link' };  var tagname = fname && tags[fname.split('.').pop()];  if (tagname !== undefined) {    var elts = document.getElementsByTagName(tagname);    for (var i in elts) {      if ((elts[i].href && elts[i].href.toString().indexOf(fname) > 0)              || (elts[i].src && elts[i].src.toString().indexOf(fname) > 0)) {        Captcha4IsLoad = true;      }    }  }  return Captcha4IsLoad;};window.initAlicom4 = function (userConfig,callback) {    var config = new Config(userConfig);    if (userConfig.https) {        config.protocol = 'https://';    } else if (!userConfig.protocol) {        config.protocol = window.location.protocol + '//';    }    if (isObject(userConfig.getType)) {        config._extend(userConfig.getType);    }    jsonp(config.apiServers , config.typePath, config, function (newConfig) {                        //错误捕获,第一个load请求可能直接报错            var newConfig = camelizeKeys(newConfig);            if(newConfig.status === 'error'){               return throwError('networkError', config, newConfig);            }            var type = newConfig.type;                        if(config.debug){                new _Object(newConfig)._extend(config.debug)            }            var init = function () {                config._extend(newConfig);                callback(new window.Captcha4(config));            };            callbacks[type] = callbacks[type] || [];            var s = status[type] || 'init';            if (s === 'init') {                status[type] = 'loading';                callbacks[type].push(init);                if(newConfig.gctPath){                    load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){                        if(err){                            throwError('networkError', config, {                                code: '60205',                                msg: 'Network failure',                                desc: {                                    detail: 'gct resource load timeout'                                }                            });                        }                    })                }                load(config,  config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers, newConfig.bypass || (newConfig.staticPath + newConfig.js), null, function (err) {                    if (err) {                        status[type] = 'fail';                        throwError('networkError', config, {                            code: '60204',                            msg: 'Network failure',                            desc: {                                detail: 'js resource load timeout'                            }                        });                    } else {                        status[type] = 'loaded';                        var cbs = callbacks[type];                        for (var i = 0, len = cbs.length; i < len; i = i + 1) {                            var cb = cbs[i];                            if (isFunction(cb)) {                                cb();                            }                        }                        callbacks[type] = [];                    }                });            } else if (s === "loaded") {                // 判断gct是否需要重新加载                if(newConfig.gctPath && !Captcha4IsLoad(newConfig.gctPath)){                // if(!Captcha4IsLoad(newConfig.gctPath)){                  load(config, config.protocol, Object.hasOwnProperty.call(config, 'staticServers') ? config.staticServers  : newConfig.staticServers || config.staticServers , newConfig.gctPath, null, function (err){                      if(err){                          throwError('networkError', config, {                              code: '60205',                              msg: 'Network failure',                              desc: {                                  detail: 'gct resource load timeout'                              }                          });                      }                  })                }                return  init();            } else if (s === "fail") {              throwError('networkError', config, {                code: '60204',                msg: 'Network failure',                desc: {                    detail: 'js resource load timeout'                }              });            } else if (s === "loading") {                callbacks[type].push(init);            }        });};})(window);
 |