@aardpro/captcha-browser
v3.0.0
Published
点击式行为验证码前端库 - Browser implementation
Maintainers
Readme
@aardpro/captcha-browser
点击式行为验证码前端库 - Browser implementation
零依赖、纯原生 JS,自带完整 UI(图片 + 状态栏 + 刷新/提交按钮 + 点击标记)。与后端 @aardpro/captcha-node 配对使用。
设计理念
组件只负责 UI(渲染、收集点击、驱动流程),网络请求和业务逻辑由调用方通过两个回调提供:
generateCaptcha()—— 你自己 fetch 后端、附加鉴权/nonce、reshape 响应,返回图片和 token;verifyCaptcha(clicks, token)—— 你自己 fetch 后端、做防重放、发短信等副作用,返回校验结果。
这样组件不绑定任何服务端约定,适配任意后端(REST / RPC / 任意响应壳子)。
功能特点
- 🎯 点击式验证:用户按从左到右顺序点击图片上的字符
- 🌐 双语:
lang: 'zh-CN' | 'en-US'(默认zh-CN),控制 widget 文案 - 🔌 后端无关:网络与业务逻辑交给回调
- 🎨 可定制:支持自定义点击标记样式
- 📦 TypeScript:完整的类型定义
- 🚀 零依赖:纯原生 JavaScript 实现
安装
# npm
npm install @aardpro/captcha-browser
# pnpm
pnpm add @aardpro/captcha-browser
# bun
bun add @aardpro/captcha-browser快速开始
import { Captcha } from '@aardpro/captcha-browser';
// 1. 提供两个回调(自行处理网络请求)
const generateCaptcha = async () => {
const response = await fetch('/api/captcha');
return await response.json(); // 期望 { success, data: { image, token } }
};
const verifyCaptcha = async (clicks, token) => {
const response = await fetch('/api/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ input: clicks, token }),
});
return await response.json(); // 期望 { success, data: { valid } }
};
// 2. 实例化(generateCaptcha / verifyCaptcha 必填)
const captcha = new Captcha({
container: '#captcha-container',
generateCaptcha,
verifyCaptcha,
});
// 3. 生成验证码(页面挂载后调用一次)
await captcha.generate();
// 4. 校验(用户按从左到右点完后调用)
const result = await captcha.verify();
// result.data.valid === true / false后端契约
两个回调的返回值必须是包装形状:
// generateCaptcha() 返回
{ success: true, data: { image: string, token: string } }
// verifyCaptcha() 返回
{ success: true, data: { valid: boolean } }用 @aardpro/captcha-node 时,把它的原始返回包一层即可:
// 生成
const { image, token } = await generateCaptcha({ chars, count: 4, secret });
return { success: true, data: { image, token } };
// 校验
const valid = verifyCaptcha({ token, input: clicks, secret });
return { success: true, data: { valid } };因为回调完全由你控制,所以防重放 nonce、鉴权头、发短信等副作用都可以直接写进
verifyCaptcha里——这是组件自己发请求的方案做不到的。
配置选项
const captcha = new Captcha({
container: '#captcha-container', // 必填:元素或选择器
width: 400, // 图片宽度,需与后端 width 一致(默认 400)
generateCaptcha, // 必填:() => Promise<{ success, data:{image,token} }>
verifyCaptcha, // 必填:(clicks, token) => Promise<{ success, data:{valid} }>
lang: 'zh-CN', // 'zh-CN' | 'en-US',默认 'zh-CN'。控制 widget 文案
markerStyle: {
color: '#667eea',
size: 24,
borderWidth: 2,
},
// 事件回调(全部可选)
onGenerate: (response) => {},
onGenerateError: (error) => {},
onClick: (coordinate, allCoordinates) => {},
onVerifySuccess: (response) => {},
onVerifyError: (error) => {},
onRefresh: () => {},
});事件监听
const captcha = new Captcha({
container: '#captcha-container',
generateCaptcha,
verifyCaptcha,
onGenerate: (response) => console.log('验证码已生成', response),
onClick: (coordinate, allCoordinates) =>
console.log('点击了', coordinate, '共', allCoordinates.length),
onVerifySuccess: (response) => console.log('验证通过!'),
onVerifyError: (error) => console.error('验证失败', error),
});API 文档
Captcha 类
构造函数
constructor(options: {
container: HTMLElement | string; // 必填
width?: number; // 默认 400
generateCaptcha: GenerateCaptchaFunction; // 必填
verifyCaptcha: VerifyCaptchaFunction; // 必填
lang?: 'zh-CN' | 'en-US'; // 默认 'zh-CN'
markerStyle?: { color?: string; size?: number; borderWidth?: number };
onGenerate?: (response: CaptchaGenerateResponse) => void;
onGenerateError?: (error: Error) => void;
onClick?: (coordinate: [number, number], allCoordinates: [number, number][]) => void;
onVerifySuccess?: (response: CaptchaVerifyResponse) => void;
onVerifyError?: (error: Error) => void;
onRefresh?: () => void;
})方法
| 方法 | 说明 |
|---|---|
| generate() | 生成验证码(调用你的 generateCaptcha),Promise<CaptchaGenerateResponse> |
| verify() | 校验点击坐标(调用你的 verifyCaptcha),Promise<CaptchaVerifyResponse> |
| refresh() | 刷新(清空并重新生成) |
| clearClicks() | 清除点击记录 |
| clearMarkers() | 清除点击标记 |
| reset() | 重置状态 |
| getClicks() | 获取点击坐标 [number, number][](相对图片左上角) |
| getToken() | 获取当前 token |
| destroy() | 销毁实例,清理 DOM 与事件 |
开发
npm install
npm run dev # 运行 demo(vite,:3000,需后端在 :3001)
npm run build # 构建(tsup)
npm run build:watchDemo
demo 里已经用回调方式对接后端(vite 会把 /api 代理到 :3001):
# 终端 1:后端(在 captcha-node/server 下)
cd ../captcha-node/server
npm install && npm start # 监听 :3001
# 终端 2:前端 demo
npm run dev # 开 http://localhost:3000不要用
file://直接打开 HTML —— module 脚本会加载失败导致一片空白,必须走npm run dev。
License
MIT
