12306的验证码一直失效(验证码除了12306)
为了防止暴力注册或爬虫爬取等机器请求,需要验证操作者是人还是机器,便有了验证码这个设计。本文作者主要介绍了如何使用 Axure 来设计一个动态的图形验证码,一起来学习一下吧。
在软件设计中,为了防止暴力注册或爬虫爬取等机器请求,需要验证操作者本尊是人还是机器,因此催生了验证码这个设计,目前验证码已经衍生出许多的形式,包括图形验证、数学运算、点选文字、滑动拼图等,本文作者主要介绍怎么使用 Axure 来设计一个动态的图形验证码。
一、验证码外观验证码的外观设计大家可以各自发挥自己的创意,以下是我绘制的,仅供大家参考:
可以给大家提供几点思路:
- 使用识别和阅读有一定难度的字体,比如带倾斜、描边或变形的一些字体
- 添加干扰因素,比如线条、背景等
- 设置跟背景相近或相似的字体颜色
原则就是能够尽可能干扰用户对文字的识别,当然,不能让用户完全识别不出来,不然就失去了它存在的意义。
二、验证码字库常规的图形验证码文字主要由大小写字母 数字组成,因此我们需要将所有会用到的文字放到字库中,生成的时候只需要从字库中挑选即可。为了方便调用,我们使用【全局变量】来存储字库,在 Axure 顶部菜单中找到【项目】,点开之后选择【全局变量】:
接着我们添加一个全局变量【code_library】并输入默认值,默认值是【0-9,A-Z,a-z】的所有字符:
三、验证码位数
一般常见图形验证码都是4位,现在也有一些平台为了提升难度,会增加到5位或6位,为了能够灵活控制验证码位数,我们也同样通过变量来控制位数的生成,在【全局变量】中添加【code_bits】,默认值是4:
四、验证码存储
我们生成验证码的时候,并不是一下子就从字库中挑选出指定位数的验证码,而是一个一个字符挑选出来,最终组成指定位数的验证码,在挑选过程中,需要有一个变量来存储已经挑选出来的字符,所以,我们还需要一个变量,用来存储生成的验证码,在【全局变量】中添加【code】,无需默认值:
五、验证码生成器
上文提到,我们需要按指定位数从字库中逐一挑选字符来组成验证码,也就是说,验证码的生成过程是一个循环的过程,因此,我们可以使用一个【动态面板】来作为验证码的生成器,当动态面板循环的时候,按照指定的位数从字库中挑选字符(动态面板如何循环调用可参考我之前发过的文章《【Axure 动态面板】让你的动画变成“永动机”》),所以,这里我们先在页面中拖入一个动态面板,并确保动态面板中至少有2个状态(状态中无需放置任何内容,Axure 9.0 建议将动态面板拖动到【负空间】):
至此,我们所有的准备工作就做完了,接下来我们就来实现验证码的生成逻辑。
六、验证码生成思路首先,我们先来拆解一下生成的步骤:
总结一下思路:
- 当验证码载入或被点击时,验证码生成器【动态面板】开始循环;
- 生成器循环时,判断验证码【code】的长度是否等于指定的位数【code_bits】,如果是,表示已经从字库【code_liabrary】中挑选出足够字符,这时可以停止生成器循环,并把验证码显示出来;
- 如果验证码的长度【code】不等于指定位数【code_bits】,表示还没有挑选出足够的字符,这个时候就从字库【code_library】随机挑选一个字符添加到验证码【code】中,直到字符数满足指定的位数,停止生成器循环并将验证码显示出来。
思路基本清晰了,但在动手之前,我们还需要知道这个设计中的一个难点,就是怎么从字库【code_library】中【随机】挑选一个字符,这里就会涉及到几个【函数表达式】:
- LVAR.charAt(index):我们可以用这个函数来从字库【code_library】中取字符,这个函数的作用是从字符串【LVAR】中取出排在【index】位置的字符,这里需要注意,【index】的索引值是从0开始的,也就是说,index = 0 表示取出第一个字符,index = 1 表示取出第二个字符,以此类推,最后一个字符的 index = LVAR.length-1。
- Math.random:我们可以用这个函数作为上述函数的索引值【index】,随机生成取值的索引,这个函数的作用是随机生成0-1的小数,如果我们要随机生成0-n的小数,我们只需要将 Math.random 乘以 n(Math.random() * n) 就行了,这个 n 的取值需要确保在字库的长度范围内,超过字库的长度范围就会取不到值,所以 n = code_library.length-1 ( index 索引是从0开始,所以要减去1,否则当 n = code_library.length 时会取不到值。
- Math.floor(x):Math.random 生成的是小数,但LVAR.charAt(index) 中的 index 必须是整数,所以我们可以通过这个函数来对Math.random 生成的小数进行取整,这个函数的作用是返回 x 的下舍整数,简单说就是将生成的结果,只保留整数,舍去小数部分,例:Math.floor(1.23) = 1。
所以要从字库中随机取值,完整的函数表达式就是:code_library.charAt(Math.floor(Math.random*(code_library.length-1)))。
这下,我们可以开始动手进行配置了。
七、生成验证码首先给验证码添加点击事件,【单击时】开启验证码生成器(动态面板)循环,循环间隔设为0毫秒即可:
接着,我们给验证码生成器添加【状态改变时】的事件,这里需要区分两种场景:
场景1:验证码位数=指定位数,表示验证码生成成功,我们只需要停止生成器循环并把验证码显示出来即可:
场景2:验证码位数≠指定位数,表示验证码未生成成功,需要从字库中随机挑选一个字符添加到验证码【code】中:
上图中后半部分的表达式上文已经解释过了,这里就不再赘述,关于为什么要在那个表达式前面加上[[code]],这里解释一下:
假设验证码生成器循环4次,每次从字库中抽出的字符分别是1、2、3、4,如果不加[[code]],则循环4次分别是以下4种结果:
- 第一次循环:1
- 第二次循环:2
- 第三次循环:3
- 第四次循环:4
从上面4次循环的结果可以看出,每次生成之后都会给【code】重新赋值,所以【code】永远都只会有一个数字,就会陷入无限的循环中,而在前面添加[[code]]之后,4次循环的结果是:
- 第一次循环:1
- 第二次循环:12
- 第三次循环:123
- 第四次循环:1234
因为每一次循环都会将之前已经生成的【code】拼接到新生成的【code】,再重新赋值给【code】,所以才能形成上述这种追加内容的效果,然后在第四次循环结束之后,验证码【code】长度满足指定长度,退出循环并显示验证码,接下来我们在浏览器中看看效果:
效果是对的,但是只有第一次点击有效,后面怎么点击都不会变化,哪里出了问题呢?
我们来分析一下,既然第一次点击能生成说明随机生成验证码的逻辑是没有问题的,那问题应该是出在判断验证码位数的那个逻辑上,原来,【code】默认是空的,所以第一次点击的时候能够正常生成,但是第二次点击的时候,因为【code】已经有值,所以不会再次生成,所以这里我们在点击验证码时,应该先清空【code】:
这样就能确保每次点击验证码时【code】都没有值,才能够正常生成,再来看看修改后的效果:
现在还有一个问题,就是验证码在载入时就会自动生成,但目前还是显示我们设置的默认文本,这里我们做个简单的优化,你可以将验证码【单击时】的事件复制粘贴到验证码【载入时】的事件中,不过这里有一种更简单的方式,就是给验证码【载入时】添加触发验证码【单击时】的事件,简单说就是在验证码载入时自动点击自身并生成:
刷新页面看看效果:
最后,来验证一下验证码位数控制的功能是否正常,将【code_bits】改为6,再看看效果:
跟预期效果是一样的,至此,全部教程结束,感谢阅读。
本文由 @产品锦李 原创发布于人人都是产品经理,未经许可,禁止转载。
题图来自Unsplash,基于CC0协议。
该文观点仅代表作者本人,人人都是产品经理平台仅提供信息存储空间服务。
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com