以前的验证码很简单,就是一个带些背景色或背景图和干扰线的纯数字字母类的验证码,现在已经发展变得很丰富了。我见过的就有好几种:纯字母数字类,数学计算类,依次点击图片上的文字类,从下列图片列表里选取符合描述的图片类,拼图验证码类。鉴于,本人要使用拼图验证码类,故介绍一下自己的调查使用情况。
我们先看看2种类型的滑动拼图验证码:
py-code-rect.png
py-code-polygon.png
第一种:拼图是简单的矩形。 这种方式可以用css(background-size和background-position)实现抠图的ui部分。你可以此插件,还不错。兼容ie9及以上。
第二种:拼图是不规则图形。 这种方式,就没法直接用css实现抠图部分了,得用canvas来做。可以参考此插件。
兼容性
此插件不兼容IE浏览器。查看项目源码,发现js使用了不少es6的新语法。
然后用Babel转了一下,发现还是有不兼容IE的方法。
比如Object.assign方法。为了兼容,补上以下代码:
// 不支持assign方法的兼容写法
if (typeof Object.assign != 'function') {
// Must be writable: true, enumerable: false, configurable: true
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) { // .length of function is 2
'use strict';
if (target == null) { // TypeError if undefined or null
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) { // Skip over if undefined or null
for (var nextKey in nextSource) {
// Avoid bugs when hasOwnProperty is shadowed
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
又比如:element.classList的相关的方法add,remove。
想兼容,请补上:
//不支持element.classList方法的兼容写法(ie10及以下)
if (!("classList" in document.documentElement)) {
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function() {
var self = this;
function update(fn) {
return function(value) {
var classes = self.className.split(/\s+/g),
index = classes.indexOf(value);
fn(classes, index, value);
self.className = classes.join(" ");
}
}
return {
add: update(function(classes, index, value) {
if (!~index) classes.push(value);
}),
remove: update(function(classes, index) {
if (~index) classes.splice(index, 1);
}),
toggle: update(function(classes, index, value) {
if (~index)
classes.splice(index, 1);
else
classes.push(value);
}),
contains: function(value) {
return !!~self.className.split(/\s+/g).indexOf(value);
},
item: function(i) {
return self.className.split(/\s+/g)[i] || null;
}
};
}
});
}
还有,当使用canvas相关相关getImageData和putImageData做抠图的代码出来时,在IE9和IE10有个图片文件跨域问题(报错:SecurityError)。
第一种解决方式:图片文件跟项目方一起就不存在跨域问题了。第二种就是不适用getImageData和putImageData方法。用其他实现方式代替,见下面带代码:
//getImageData方法和putImageData方法在IE9和IE10上,涉及到文件路径的跨域访问问题。
// console.log('(x:'+_this.x+',y:'+_this.y+')');
if(navigator.userAgent.indexOf("MSIE") > -1){
_this.block.style.marginLeft = '-'+(_this.x-3)+'px';//不抵边,空3px
}else{
var ImageData = _this.blockCtx.getImageData(_this.x - 3, y, L, L);
_this.block.width = L;
_this.blockCtx.putImageData(ImageData, 0, y);
}
还有,在IE中,在canvas上绘图有顺序步骤的。如果在IE中出现下图抠图区未绘制成功,请调整代码顺序。
py-code-error1.png
解决方式:
py-code-sx.png
最终调整完后的demo,见js实现滑动拼图验证码
另外,提供2种三方的现成的调用api:极验和腾讯防水墙。