├── 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 |
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 |
--------------------------------------------------------------------------------