├── README.md ├── css └── style.css ├── index.html └── js └── gt.js /README.md: -------------------------------------------------------------------------------- 1 | # geetest-validator 2 | 3 | + 极验验证器 调试工具 测试用 4 | + 按顺序填写/点击5步 可以拿到验证结果 5 | 6 | ### www 7 | 8 | - gitpage访问 https://kuresaru.github.io/geetest-validator/ 9 | - 个人站备用 https://www.scraft.top/gtv/ 10 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 50px 0; 3 | text-align: center; 4 | font-family: "PingFangSC-Regular", "Open Sans", Arial, "Hiragino Sans GB", "Microsoft YaHei", "STHeiti", "WenQuanYi Micro Hei", SimSun, sans-serif; 5 | } 6 | 7 | .inp { 8 | border: 1px solid #cccccc; 9 | border-radius: 2px; 10 | padding: 0 10px; 11 | width: 320px; 12 | height: 40px; 13 | font-size: 18px; 14 | } 15 | 16 | .btn { 17 | display: inline-block; 18 | box-sizing: border-box; 19 | border: 1px solid #cccccc; 20 | border-radius: 2px; 21 | width: 100px; 22 | height: 40px; 23 | line-height: 40px; 24 | font-size: 16px; 25 | color: #666; 26 | cursor: pointer; 27 | background: white linear-gradient(180deg, #ffffff 0%, #f3f3f3 100%); 28 | } 29 | 30 | .btn:hover { 31 | background: white linear-gradient(0deg, #ffffff 0%, #f3f3f3 100%) 32 | } 33 | 34 | #captcha { 35 | width: 300px; 36 | display: inline-block; 37 | } 38 | 39 | label { 40 | vertical-align: top; 41 | display: inline-block; 42 | width: 120px; 43 | text-align: right; 44 | } 45 | 46 | #text { 47 | height: 42px; 48 | width: 298px; 49 | text-align: center; 50 | border-radius: 2px; 51 | background-color: #F3F3F3; 52 | color: #BBBBBB; 53 | font-size: 14px; 54 | letter-spacing: 0.1px; 55 | line-height: 42px; 56 | } 57 | 58 | #wait { 59 | display: none; 60 | height: 42px; 61 | width: 298px; 62 | text-align: center; 63 | border-radius: 2px; 64 | background-color: #F3F3F3; 65 | } 66 | 67 | .loading { 68 | margin: auto; 69 | width: 70px; 70 | height: 20px; 71 | } 72 | 73 | .loading-dot { 74 | float: left; 75 | width: 8px; 76 | height: 8px; 77 | margin: 18px 4px; 78 | background: #ccc; 79 | 80 | -webkit-border-radius: 50%; 81 | -moz-border-radius: 50%; 82 | border-radius: 50%; 83 | 84 | opacity: 0; 85 | 86 | -webkit-box-shadow: 0 0 2px black; 87 | -moz-box-shadow: 0 0 2px black; 88 | -ms-box-shadow: 0 0 2px black; 89 | -o-box-shadow: 0 0 2px black; 90 | box-shadow: 0 0 2px black; 91 | 92 | -webkit-animation: loadingFade 1s infinite; 93 | -moz-animation: loadingFade 1s infinite; 94 | animation: loadingFade 1s infinite; 95 | } 96 | 97 | .loading-dot:nth-child(1) { 98 | -webkit-animation-delay: 0s; 99 | -moz-animation-delay: 0s; 100 | animation-delay: 0s; 101 | } 102 | 103 | .loading-dot:nth-child(2) { 104 | -webkit-animation-delay: 0.1s; 105 | -moz-animation-delay: 0.1s; 106 | animation-delay: 0.1s; 107 | } 108 | 109 | .loading-dot:nth-child(3) { 110 | -webkit-animation-delay: 0.2s; 111 | -moz-animation-delay: 0.2s; 112 | animation-delay: 0.2s; 113 | } 114 | 115 | .loading-dot:nth-child(4) { 116 | -webkit-animation-delay: 0.3s; 117 | -moz-animation-delay: 0.3s; 118 | animation-delay: 0.3s; 119 | } 120 | 121 | @-webkit-keyframes loadingFade { 122 | 0% { opacity: 0; } 123 | 50% { opacity: 0.8; } 124 | 100% { opacity: 0; } 125 | } 126 | 127 | @-moz-keyframes loadingFade { 128 | 0% { opacity: 0; } 129 | 50% { opacity: 0.8; } 130 | 100% { opacity: 0; } 131 | } 132 | 133 | @keyframes loadingFade { 134 | 0% { opacity: 0; } 135 | 50% { opacity: 0.8; } 136 | 100% { opacity: 0; } 137 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 |
16 |
17 | 18 |
19 | 20 | 21 |
22 |
23 | 24 |
3. 生成
25 |

26 | 27 |
28 | 29 |
30 |
31 | 请先生成 32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 45 |
5. 结果
46 |

47 | 48 |
49 | 50 | 51 |
52 |
53 | 54 |
55 | 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 | 64 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /js/gt.js: -------------------------------------------------------------------------------- 1 | "v0.4.8 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 = year + '-' + month + '-' + day + " " + hours + ":" + minutes + ":" + seconds; 115 | return currentdate; 116 | } 117 | 118 | var random = function () { 119 | return parseInt(Math.random() * 10000) + (new Date()).valueOf(); 120 | }; 121 | 122 | var loadScript = function (url, cb) { 123 | var script = document.createElement("script"); 124 | script.charset = "UTF-8"; 125 | script.async = true; 126 | 127 | // 对geetest的静态资源添加 crossOrigin 128 | if ( /static\.geetest\.com/g.test(url)) { 129 | script.crossOrigin = "anonymous"; 130 | } 131 | 132 | script.onerror = function () { 133 | cb(true); 134 | }; 135 | var loaded = false; 136 | script.onload = script.onreadystatechange = function () { 137 | if (!loaded && 138 | (!script.readyState || 139 | "loaded" === script.readyState || 140 | "complete" === script.readyState)) { 141 | 142 | loaded = true; 143 | setTimeout(function () { 144 | cb(false); 145 | }, 0); 146 | } 147 | }; 148 | script.src = url; 149 | head.appendChild(script); 150 | }; 151 | 152 | var normalizeDomain = function (domain) { 153 | // special domain: uems.sysu.edu.cn/jwxt/geetest/ 154 | // return domain.replace(/^https?:\/\/|\/.*$/g, ''); uems.sysu.edu.cn 155 | return domain.replace(/^https?:\/\/|\/$/g, ''); // uems.sysu.edu.cn/jwxt/geetest 156 | }; 157 | var normalizePath = function (path) { 158 | path = path.replace(/\/+/g, '/'); 159 | if (path.indexOf('/') !== 0) { 160 | path = '/' + path; 161 | } 162 | return path; 163 | }; 164 | var normalizeQuery = function (query) { 165 | if (!query) { 166 | return ''; 167 | } 168 | var q = '?'; 169 | new _Object(query)._each(function (key, value) { 170 | if (isString(value) || isNumber(value) || isBoolean(value)) { 171 | q = q + encodeURIComponent(key) + '=' + encodeURIComponent(value) + '&'; 172 | } 173 | }); 174 | if (q === '?') { 175 | q = ''; 176 | } 177 | return q.replace(/&$/, ''); 178 | }; 179 | var makeURL = function (protocol, domain, path, query) { 180 | domain = normalizeDomain(domain); 181 | 182 | var url = normalizePath(path) + normalizeQuery(query); 183 | if (domain) { 184 | url = protocol + domain + url; 185 | } 186 | 187 | return url; 188 | }; 189 | 190 | var load = function (config, send, protocol, domains, path, query, cb) { 191 | var tryRequest = function (at) { 192 | 193 | var url = makeURL(protocol, domains[at], path, query); 194 | loadScript(url, function (err) { 195 | if (err) { 196 | if (at >= domains.length - 1) { 197 | cb(true); 198 | // report gettype error 199 | if (send) { 200 | config.error_code = 508; 201 | var url = protocol + domains[at] + path; 202 | reportError(config, url); 203 | } 204 | } else { 205 | tryRequest(at + 1); 206 | } 207 | } else { 208 | cb(false); 209 | } 210 | }); 211 | }; 212 | tryRequest(0); 213 | }; 214 | 215 | 216 | var jsonp = function (domains, path, config, callback) { 217 | if (isObject(config.getLib)) { 218 | config._extend(config.getLib); 219 | callback(config); 220 | return; 221 | } 222 | if (config.offline) { 223 | callback(config._get_fallback_config()); 224 | return; 225 | } 226 | 227 | var cb = "geetest_" + random(); 228 | window[cb] = function (data) { 229 | if (data.status == 'success') { 230 | callback(data.data); 231 | } else if (!data.status) { 232 | callback(data); 233 | } else { 234 | callback(config._get_fallback_config()); 235 | } 236 | window[cb] = undefined; 237 | try { 238 | delete window[cb]; 239 | } catch (e) { 240 | } 241 | }; 242 | load(config, true, config.protocol, domains, path, { 243 | gt: config.gt, 244 | callback: cb 245 | }, function (err) { 246 | if (err) { 247 | callback(config._get_fallback_config()); 248 | } 249 | }); 250 | }; 251 | 252 | var reportError = function (config, url) { 253 | load(config, false, config.protocol, ['monitor.geetest.com'], '/monitor/send', { 254 | time: nowDate(), 255 | captcha_id: config.gt, 256 | challenge: config.challenge, 257 | pt: pt, 258 | exception_url: url, 259 | error_code: config.error_code 260 | }, function (err) {}) 261 | } 262 | 263 | var throwError = function (errorType, config) { 264 | var errors = { 265 | networkError: '网络错误', 266 | gtTypeError: 'gt字段不是字符串类型' 267 | }; 268 | if (typeof config.onError === 'function') { 269 | config.onError(errors[errorType]); 270 | } else { 271 | throw new Error(errors[errorType]); 272 | } 273 | }; 274 | 275 | var detect = function () { 276 | return window.Geetest || document.getElementById("gt_lib"); 277 | }; 278 | 279 | if (detect()) { 280 | status.slide = "loaded"; 281 | } 282 | 283 | window.initGeetest = function (userConfig, callback) { 284 | 285 | var config = new Config(userConfig); 286 | 287 | if (userConfig.https) { 288 | config.protocol = 'https://'; 289 | } else if (!userConfig.protocol) { 290 | config.protocol = window.location.protocol + '//'; 291 | } 292 | 293 | // for KFC 294 | if (userConfig.gt === '050cffef4ae57b5d5e529fea9540b0d1' || 295 | userConfig.gt === '3bd38408ae4af923ed36e13819b14d42') { 296 | config.apiserver = 'yumchina.geetest.com/'; // for old js 297 | config.api_server = 'yumchina.geetest.com'; 298 | } 299 | 300 | if(userConfig.gt){ 301 | window.GeeGT = userConfig.gt 302 | } 303 | 304 | if(userConfig.challenge){ 305 | window.GeeChallenge = userConfig.challenge 306 | } 307 | 308 | if (isObject(userConfig.getType)) { 309 | config._extend(userConfig.getType); 310 | } 311 | jsonp([config.api_server || config.apiserver], config.typePath, config, function (newConfig) { 312 | var type = newConfig.type; 313 | var init = function () { 314 | config._extend(newConfig); 315 | callback(new window.Geetest(config)); 316 | }; 317 | 318 | callbacks[type] = callbacks[type] || []; 319 | var s = status[type] || 'init'; 320 | if (s === 'init') { 321 | status[type] = 'loading'; 322 | 323 | callbacks[type].push(init); 324 | 325 | load(config, true, config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) { 326 | if (err) { 327 | status[type] = 'fail'; 328 | throwError('networkError', config); 329 | } else { 330 | status[type] = 'loaded'; 331 | var cbs = callbacks[type]; 332 | for (var i = 0, len = cbs.length; i < len; i = i + 1) { 333 | var cb = cbs[i]; 334 | if (isFunction(cb)) { 335 | cb(); 336 | } 337 | } 338 | callbacks[type] = []; 339 | } 340 | }); 341 | } else if (s === "loaded") { 342 | init(); 343 | } else if (s === "fail") { 344 | throwError('networkError', config); 345 | } else if (s === "loading") { 346 | callbacks[type].push(init); 347 | } 348 | }); 349 | 350 | }; 351 | 352 | 353 | })(window); 354 | 355 | --------------------------------------------------------------------------------