官网:https://docs.geetest.com/sensebot/apirefer/api/web
流程与原理
待补充……
方法
1.引入极验js,调用初始化方法
require("~/plugins/geetest.js");
this.handleGtInit();
2.先和服务端进行一次验证,验证后返回相关信息,带着相关信息进行二次验证
handleGtInit(status) {
let _this = this;
this.gtLoadStatus = true;
this.getGtInit().then(res => {
_this.gt_server_status = res.gt_server_status;
window.initGeetest(
{
gt: res.gt,
challenge: res.challenge,
width: "100%",
product: "embed", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效
offline: !res.success, // 表示用户后台检测极验服务器是否宕机,一般不需要关注
new_captcha: true
},
function (catchaObj) {
catchaObj.appendTo("#captcha");
catchaObj.onReady(function () {
if (status === "1") {
_this.waitShow = false;
}
this.gtLoadStatus = false;
});
catchaObj.onSuccess(function () {
_this.geetest_challenge = catchaObj.getValidate().geetest_challenge;
_this.geetest_validate = catchaObj.getValidate().geetest_validate;
_this.geetest_seccode = catchaObj.getValidate().geetest_seccode;
if (_this.checkTelephone()) {
_this.SecondCheckGt().then(res => {
if (res.code === 200) {
_this.dragSuccess = true; // 必须用_this, 否则在这里做的对于this的改变无效
_this.showErrTips = false;
} else {
_this.msg = "出错啦,请稍后重试";
_this.showPop = true;
}
});
} else {
_this.reLoadGtCode();
return;
}
});
catchaObj.onError(function () {
this.msg = "出错啦,请稍后重试";
this.showPop = true;
});
}
);
});
},
async getGtInit() {
let info = {};
await getGtInitInfo(this).then(res => {
let {code, message} = res;
if (code !== 200) {
this.this.showErrTips = true;
this.errMessage = message;
} else {
info = res.data;
}
});
return info;
},
3.重置验证
reLoadGtCode() {
document.getElementById("captcha").innerHTML = "";
this.gtLoadStatus = false;
this.handleGtInit();
},
4.二次验证
async SecondCheckGt() {
let res = await postCheckGt(this, {
challenge: this.geetest_challenge,
validate: this.geetest_validate,
seccode: this.geetest_seccode,
gt_server_status: this.gt_server_status
});
let {code, message} = res;
if (code !== 200) {
this.this.showErrTips = true;
this.errMessage = message;
}
return res;
},
5.校验手机号
// 校验手机号
checkTelephone() {
let phoneReg = "";
if (this.global_num == "+86") {
phoneReg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; // 验证电话号码正则
} else {
phoneReg = /^([0-9]+|0)$/; //手机号必须为数字
}
if (!phoneReg.test(this.telephone)) {
this.showErrTips = true;
this.errMessage = "请输入正确的手机号";
return false;
}
return true;
},
6.获取手机验证码
//图形验证码是否正确&发送短信
sendMessage() {
this.newPhone = this.global_num + "-" + this.telephone;
return postSmsCode(this, {
phone: this.newPhone,
smscode_type: 2, // 2为注册,
geetest_challenge: this.geetest_challenge
}).then(res => {
let {message, code} = res;
if (code !== 200) {
this.showErrTips = true;
this.errMessage = message;
return false;
}
return true;
});
},
7.极验封装方法geetest.js
"v0.4.7 Geetest Inc.";
(function (window) {
"use strict";
if (typeof window === 'undefined') {
throw new Error('Geetest requires browser environment');
}
var document = window.document;
var Math = window.Math;
var head = document.getElementsByTagName("Head")[0];
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;
}
};
function Config(config) {
var self = this;
new _Object(config)._each(function (key, value) {
self[key] = value;
});
}
Config.prototype = {
api_server: 'api.geetest.com',
protocol: 'https://',
typePath: '/gettype.php',
fallback_config: {
slide: {
static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
type: 'slide',
slide: '/static/js/geetest.0.0.0.js'
},
fullpage: {
static_servers: ["static.geetest.com", "dn-staticdown.qbox.me"],
type: 'fullpage',
fullpage: '/static/js/fullpage.0.0.0.js'
}
},
_get_fallback_config: function () {
var self = this;
if (isString(self.type)) {
return self.fallback_config[self.type];
} else if (self.new_captcha) {
return self.fallback_config.fullpage;
} else {
return self.fallback_config.slide;
}
},
_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 pt = MOBILE ? 3 : 0;
var callbacks = {};
var status = {};
var nowDate = function () {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
if (month >= 1 && month <= 9) {
month = '0' + month;
}
if (day >= 0 && day <= 9) {
day = '0' + day;
}
if (hours >= 0 && hours <= 9) {
hours = '0' + hours;
}
if (minutes >= 0 && minutes <= 9) {
minutes = '0' + minutes;
}
if (seconds >= 0 && seconds <= 9) {
seconds = '0' + seconds;
}
var currentdate = year + '-' + month + '-' + day + " " + hours + ":" + minutes + ":" + seconds;
return currentdate;
}
var random = function () {
return parseInt(Math.random() * 10000) + (new Date()).valueOf();
};
var loadScript = function (url, cb) {
var script = document.createElement("script");
script.charset = "UTF-8";
script.async = true;
script.onerror = function () {
cb(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);
};
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.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, send, protocol, domains, path, query, cb) {
var tryRequest = function (at) {
var url = makeURL(protocol, domains[at], path, query);
loadScript(url, function (err) {
if (err) {
if (at >= domains.length - 1) {
cb(true);
// report gettype error
if (send) {
config.error_code = 508;
var url = protocol + domains[at] + path;
reportError(config, url);
}
} else {
tryRequest(at + 1);
}
} else {
cb(false);
}
});
};
tryRequest(0);
};
var jsonp = function (domains, path, config, callback) {
if (isObject(config.getLib)) {
config._extend(config.getLib);
callback(config);
return;
}
if (config.offline) {
callback(config._get_fallback_config());
return;
}
var cb = "geetest_" + random();
window[cb] = function (data) {
if (data.status == 'success') {
callback(data.data);
} else if (!data.status) {
callback(data);
} else {
callback(config._get_fallback_config());
}
window[cb] = undefined;
try {
delete window[cb];
} catch (e) {
}
};
load(config, true, config.protocol, domains, path, {
gt: config.gt,
callback: cb
}, function (err) {
if (err) {
callback(config._get_fallback_config());
}
});
};
var reportError = function (config, url) {
load(config, false, config.protocol, ['monitor.geetest.com'], '/monitor/send', {
time: nowDate(),
captcha_id: config.gt,
challenge: config.challenge,
pt: pt,
exception_url: url,
error_code: config.error_code
}, function (err) {})
}
var throwError = function (errorType, config) {
var errors = {
networkError: '网络错误',
gtTypeError: 'gt字段不是字符串类型'
};
if (typeof config.onError === 'function') {
config.onError(errors[errorType]);
} else {
throw new Error(errors[errorType]);
}
};
var detect = function () {
return window.Geetest || document.getElementById("gt_lib");
};
if (detect()) {
status.slide = "loaded";
}
window.initGeetest = function (userConfig, callback) {
var config = new Config(userConfig);
if (userConfig.https) {
config.protocol = 'https://';
} else if (!userConfig.protocol) {
config.protocol = window.location.protocol + '//';
}
// for KFC
if (userConfig.gt === '050cffef4ae57b5d5e529fea9540b0d1' ||
userConfig.gt === '3bd38408ae4af923ed36e13819b14d42') {
config.apiserver = 'yumchina.geetest.com/'; // for old js
config.api_server = 'yumchina.geetest.com';
}
if (isObject(userConfig.getType)) {
config._extend(userConfig.getType);
}
jsonp([config.api_server || config.apiserver], config.typePath, config, function (newConfig) {
var type = newConfig.type;
var init = function () {
config._extend(newConfig);
callback(new window.Geetest(config));
};
callbacks[type] = callbacks[type] || [];
var s = status[type] || 'init';
if (s === 'init') {
status[type] = 'loading';
callbacks[type].push(init);
load(config, true, config.protocol, newConfig.static_servers || newConfig.domains, newConfig[type] || newConfig.path, null, function (err) {
if (err) {
status[type] = 'fail';
throwError('networkError', config);
} 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") {
init();
} else if (s === "fail") {
throwError('networkError', config);
} else if (s === "loading") {
callbacks[type].push(init);
}
});
};
})(window);
function gtInit() {
}
export default {
gtInit
}