当前位置:首页 > JavaScript

js验证码的实现

2026-01-15 14:47:55JavaScript

验证码的基本实现原理

验证码(CAPTCHA)的核心目标是区分人类用户和自动化程序。JavaScript可用于生成或验证客户端验证码,但需注意纯前端验证可能被绕过,通常需结合后端验证。

纯前端验证码实现示例

以下是一个简单的数字验证码生成与验证的前端实现:

// 生成随机验证码
function generateCaptcha() {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  let captcha = '';
  for (let i = 0; i < 6; i++) {
    captcha += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  document.getElementById('captchaDisplay').textContent = captcha;
  return captcha;
}

let currentCaptcha = generateCaptcha();

// 验证用户输入
function validateCaptcha() {
  const userInput = document.getElementById('captchaInput').value;
  if (userInput === currentCaptcha) {
    alert('验证码正确');
    return true;
  } else {
    alert('验证码错误');
    generateCaptcha();
    return false;
  }
}

结合Canvas的图形验证码

更安全的实现方式是通过Canvas生成图形验证码:

function drawCaptcha() {
  const canvas = document.getElementById('captchaCanvas');
  const ctx = canvas.getContext('2d');
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 生成随机字符串
  const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
  let captchaText = '';
  for (let i = 0; i < 6; i++) {
    captchaText += chars.charAt(Math.floor(Math.random() * chars.length));
  }

  // 绘制背景和干扰元素
  ctx.fillStyle = '#f0f0f0';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  // 绘制文本
  for (let i = 0; i < captchaText.length; i++) {
    ctx.font = '24px Arial';
    ctx.fillStyle = getRandomColor();
    ctx.fillText(
      captchaText[i],
      15 + i * 20,
      30 + Math.random() * 10
    );
  }

  // 绘制干扰线
  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;
}

后端验证的必要性

前端验证码容易被绕过,应结合后端验证:

  1. 服务端生成验证码文本并存储(如Session)
  2. 将验证码图像发送到客户端
  3. 用户提交后,服务端比对存储的验证码

Node.js示例:

// Express服务端示例
const express = require('express');
const session = require('express-session');
const app = express();

app.use(session({ secret: 'your-secret-key', resave: false, saveUninitialized: true }));

app.get('/captcha', (req, res) => {
  const captcha = generateRandomString();
  req.session.captcha = captcha;

  // 生成图像并发送
  const canvas = createCanvas(150, 50);
  // ...绘制验证码图像...
  res.set('Content-Type', 'image/png');
  canvas.pngStream().pipe(res);
});

app.post('/verify', (req, res) => {
  if (req.body.captcha === req.session.captcha) {
    res.send('验证成功');
  } else {
    res.status(400).send('验证码错误');
  }
});

增强安全性的措施

  1. 限制验证码尝试次数
  2. 设置验证码有效期(通常2-5分钟)
  3. 使用更复杂的验证方式,如行为验证(拖动滑块、点击特定区域等)
  4. 定期更换验证码生成算法

使用第三方验证码服务

对于高安全性需求,可考虑专业验证码服务:

  • Google reCAPTCHA
  • hCaptcha
  • 腾讯验证码

这些服务通常提供JavaScript集成方式,如reCAPTCHA v2:

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<div class="g-recaptcha" data-sitekey="your-site-key"></div>

后端需验证返回的token:

const axios = require('axios');

async function verifyRecaptcha(token) {
  const response = await axios.post(
    'https://www.google.com/recaptcha/api/siteverify',
    `secret=your-secret-key&response=${token}`
  );
  return response.data.success;
}

js验证码的实现

标签: 验证码js
分享给朋友:

相关文章

js实现倒计时

js实现倒计时

使用 setInterval 实现倒计时 通过 setInterval 定时器每秒更新剩余时间,适用于简单倒计时场景。 function countdown(seconds, callbac…

js 实现继承

js 实现继承

原型链继承 通过让子类的原型对象指向父类的实例来实现继承。子类实例可以访问父类原型上的属性和方法。 function Parent() { this.name = 'parent'; } Par…

js实现验证

js实现验证

验证表单输入 使用JavaScript验证表单输入是常见的需求。可以通过监听表单提交事件,检查输入字段是否符合要求。 document.getElementById('myForm').addEve…

php验证码实现

php验证码实现

验证码实现方法 在PHP中实现验证码功能通常涉及生成随机字符串或数字,将其转换为图像,并通过会话(Session)进行验证。以下是几种常见的实现方式: 使用GD库生成图像验证码 GD库是PHP内置…

js防抖和节流实现

js防抖和节流实现

防抖(Debounce)的实现 防抖的核心思想是在事件被触发后,延迟执行回调函数。如果在延迟时间内再次触发事件,则重新计时。适用于输入框搜索、窗口大小调整等场景。 function debounce…

js 实现分页

js 实现分页

实现分页的基本逻辑 分页功能通常需要后端返回数据总量或总页数,前端根据当前页码和每页条数截取对应数据。以下是一个基于JavaScript的简单分页实现方案: 前端分页实现 假设已有从后端获取的完整数…