用js实现验证码
实现基础验证码生成与验证
验证码通常由随机字符或数字组成,可通过以下方式实现基础功能:
// 生成4位随机数字验证码
function generateCaptcha() {
const captcha = Math.floor(1000 + Math.random() * 9000);
return captcha.toString();
}
// 验证用户输入
function validateCaptcha(userInput, generatedCaptcha) {
return userInput === generatedCaptcha;
}
// 使用示例
const captcha = generateCaptcha();
console.log('生成的验证码:', captcha); // 例如输出: 生成的验证码: 4728
图形验证码实现
创建包含干扰元素的canvas图形验证码更安全:
// 生成图形验证码
function createImageCaptcha(canvasId) {
const canvas = document.getElementById(canvasId);
const ctx = canvas.getContext('2d');
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
let captchaText = '';
// 生成5位随机字符
for(let i = 0; i < 5; i++) {
captchaText += chars.charAt(Math.floor(Math.random() * chars.length));
}
// 绘制背景和文字
ctx.fillStyle = '#f3f3f3';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.font = '30px Arial';
ctx.fillStyle = '#232323';
ctx.fillText(captchaText, 30, 35);
// 添加干扰线
for(let i = 0; i < 5; i++) {
ctx.strokeStyle = getRandomColor();
ctx.beginPath();
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.stroke();
}
return captchaText;
}
function getRandomColor() {
const letters = '0123456789ABCDEF';
let color = '#';
for(let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
}
HTML部分需要包含canvas元素:
<canvas id="captchaCanvas" width="150" height="50"></canvas>
<button onclick="refreshCaptcha()">刷新验证码</button>
<script>
let currentCaptcha;
window.onload = function() {
currentCaptcha = createImageCaptcha('captchaCanvas');
};
function refreshCaptcha() {
currentCaptcha = createImageCaptcha('captchaCanvas');
}
function checkCaptcha() {
const userInput = document.getElementById('captchaInput').value;
if(userInput === currentCaptcha) {
alert('验证码正确');
} else {
alert('验证码错误');
refreshCaptcha();
}
}
</script>
增加安全性的改进方案
为防止自动化工具识别,可考虑以下增强措施:
// 扭曲文字增强安全性
function distortText(ctx, text, x, y) {
ctx.save();
ctx.translate(x, y);
// 水平扭曲
for(let i = 0; i < text.length; i++) {
ctx.save();
ctx.translate(i * 20, 0);
ctx.rotate(Math.random() * 0.5 - 0.25);
ctx.fillText(text[i], 0, 0);
ctx.restore();
}
ctx.restore();
}
// 在createImageCaptcha函数中用distortText替换fillText
ctx.fillStyle = '#232323';
distortText(ctx, captchaText, 30, 35);
验证码时效性控制
为验证码添加有效期限制:
// 带时效的验证码存储
const captchaStorage = {};
function generateTimedCaptcha(id, expiresIn = 300000) { // 默认5分钟
const captcha = generateCaptcha();
captchaStorage[id] = {
value: captcha,
expires: Date.now() + expiresIn
};
return captcha;
}
function validateTimedCaptcha(id, userInput) {
const stored = captchaStorage[id];
if(!stored) return false;
if(Date.now() > stored.expires) {
delete captchaStorage[id];
return false;
}
return userInput === stored.value;
}
滑动验证码实现
更现代的滑动验证码基础实现:
// 滑动验证码基础逻辑
let startX, isDragging = false;
const slider = document.getElementById('slider');
const track = document.getElementById('track');
const thumb = document.getElementById('thumb');
const target = document.getElementById('target');
thumb.addEventListener('mousedown', (e) => {
isDragging = true;
startX = e.clientX;
});
document.addEventListener('mousemove', (e) => {
if(!isDragging) return;
const deltaX = e.clientX - startX;
thumb.style.left = Math.min(Math.max(deltaX, 0), track.offsetWidth - thumb.offsetWidth) + 'px';
});
document.addEventListener('mouseup', () => {
if(!isDragging) return;
isDragging = false;
const thumbRect = thumb.getBoundingClientRect();
const targetRect = target.getBoundingClientRect();
// 检查是否对齐目标区域
if(Math.abs(thumbRect.left - targetRect.left) < 10) {
alert('验证成功');
} else {
thumb.style.left = '0px';
alert('请重新尝试');
}
});
对应的HTML结构:
<div id="track" style="width:300px;height:40px;background:#eee;position:relative;">
<div id="target" style="width:40px;height:40px;background:#555;position:absolute;right:50px;"></div>
<div id="thumb" style="width:40px;height:40px;background:#333;position:absolute;cursor:move;"></div>
</div>
这些实现方案可根据实际需求组合使用或进一步扩展,图形验证码方案适合传统表单提交,滑动验证码更适合现代Web应用。安全性要求高的场景建议结合后端验证逻辑。







