npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sbsbok/slider-captcha

v1.0.0

Published

A lightweight slider captcha component for web applications with PC and mobile support

Readme

Slider Captcha 滑块式验证码

English | 中文


项目概述

Slider Captcha 是一款轻量级的滑块式验证码组件,支持 PC 端及移动端 Web 应用。用户通过拖动滑块完成拼图验证,组件会记录拖动行为的时间、精度和滑动轨迹等信息,可发送至服务器进行后台算法验证,有效防止自动化脚本攻击。

本项目基于 TypeScript 开发,提供简洁的 API 接口,易于集成到各类 Web 项目中。

核心功能与特性

  • 拖动验证:用户通过拖动滑块填充拼图完成校验
  • 轨迹检测:记录用户滑动轨迹,可用于后台行为分析
  • 响应式设计:完美适配 PC 端和移动端设备
  • 触摸支持:支持 touch 事件,适配移动端浏览器
  • 多种验证模式:支持本地验证和远程服务器验证
  • 灵活配置:提供丰富的配置选项,可自定义外观和行为
  • 图片加载容错:支持远程图片和本地备用图片自动切换
  • Canvas 渲染:使用 Canvas 绘制拼图和滑块,效果清晰

环境要求

  • 现代浏览器(Chrome、Firefox、Safari、Edge 等)
  • 支持 HTML5 Canvas API
  • 支持 ES6+ JavaScript
  • 可选:jQuery(仅在使用默认远程验证功能时需要)

安装与配置

方式一:npm / pnpm 安装(推荐)

# 使用 npm 安装
npm install @sbsbok/slider-captcha

# 或使用 pnpm 安装
pnpm add @sbsbok/slider-captcha

在项目中引入

import SliderCaptcha from '@sbsbok/slider-captcha';
import '@sbsbok/slider-captcha/dist/slidercaptcha.min.css';

方式二:直接引入(适用于原生 HTML 项目)

1. 引入 CSS 样式

<link rel="stylesheet" href="./src/slidercaptcha.min.css" />

将上述代码添加到 <head> 标签中,并确保在其他样式表之前引入。

2. 引入 JavaScript 脚本

<script src="./src/longbow.slidercaptcha.ts"></script>

将脚本标签放置在 </body> 之前。

方式三:在 Vue / React / TypeScript 项目中使用

import SliderCaptcha from '@/common/longbow.slidercaptcha';
import '@/common/slidercaptcha.min.css';

快速开始

基础用法

在页面中添加验证码容器元素:

<div id="captcha"></div>

通过 JavaScript 初始化验证码:

sliderCaptcha({
	id: 'captcha',
});

在 Vue 3 中的使用示例

<template>
	<div class="card-body relative">
		<div v-if="showCaptcha" class="absolute w-full h-full top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] z-50">
			<el-icon class="absolute text-center cursor-pointer top-[10%] left-[75%] z-80" color="black" size="35" @click="refresh">
				<Refresh />
			</el-icon>
			<div id="captcha" class="bg-white rounded-lg shadow-xl p-4"></div>
		</div>
	</div>
</template>

<script setup lang="ts">
import { ref, nextTick } from 'vue';
import SliderCaptcha from '@/common/longbow.slidercaptcha';

const showCaptcha = ref(true);
const captcha = ref<SliderCaptcha | null>(null);

const initCaptcha = async () => {
	await nextTick();
	captcha.value = new SliderCaptcha(document.querySelector('#captcha')!, {
		width: 280,
		height: 150,
		sliderL: 42,
		sliderR: 9,
		offset: 5,
		loadingText: '正在加载中...',
		failedText: '再试一次',
		barText: '向右滑动填充拼图',
		repeatIcon: 'iconfont iconfont-shuaxin',
		onSuccess: () => {
			console.log('验证成功');
			showCaptcha.value = false;
			captcha.value = null;
		},
		onFail: () => {
			console.log('验证失败');
		},
		onRefresh: () => {
			console.log('验证码刷新');
		},
	});
};

const refresh = () => {
	captcha.value?.reset();
};

initCaptcha();
</script>

API 接口说明

配置选项(Options)

| 参数 | 类型 | 默认值 | 说明 | | -------------- | -------- | --------------------------- | ------------------------------------------------- | | id | string | 必填 | 容器元素的 ID | | width | integer | 280 | 验证码背景图片宽度(单位:像素) | | height | integer | 155 | 验证码背景图片高度(单位:像素) | | sliderL | integer | 42 | 滑块拼图宽度(单位:像素) | | sliderR | integer | 9 | 滑块拼图突出半径(单位:像素) | | offset | integer | 5 | 验证容错偏差值,默认为 5 个像素偏差即认为验证通过 | | loadingText | string | "正在加载中..." | 图片加载过程中显示的文本信息 | | failedText | string | "再试一次" | 验证失败时显示的文本信息 | | barText | string | "向右滑动填充拼图" | 拖动滑块前显示的提示文本信息 | | repeatIcon | string | "iconfont iconfont-shuaxin" | 刷新按钮图标类名,需引用对应的图标库 | | maxLoadCount | integer | 3 | 图片最大加载重试次数 | | setSrc | function | 随机图片 | 设置图片加载路径,返回图片 URL | | localImages | function | 本地备用图片 | 图片加载失败时调用的回调,返回本地备用图片路径 | | remoteUrl | string | null | 服务器端验证请求地址,设置为 null 则使用本地验证 | | verify | function | 本地验证逻辑 | 自定义服务器端验证方法 | | onSuccess | function | - | 验证成功时的回调函数,参数为滑动轨迹数组 | | onFail | function | - | 验证失败时的回调函数 | | onRefresh | function | - | 点击刷新按钮时的回调函数 |

使用示例

sliderCaptcha({
	id: 'captcha',
	width: 280,
	height: 150,
	sliderL: 42,
	sliderR: 9,
	offset: 5,
	loadingText: '正在加载中...',
	failedText: '再试一次',
	barText: '向右滑动填充拼图',
	repeatIcon: 'iconfont iconfont-shuaxin',
	setSrc: function () {
		return 'https://imgs.blazor.zone/images/Pic' + Math.round(Math.random() * 136) + '.jpg';
	},
	onSuccess: function (trail) {
		console.log('验证成功,滑动轨迹:', trail);
	},
	onFail: function () {
		console.log('验证失败');
	},
	onRefresh: function () {
		console.log('验证码已刷新');
	},
});

方法(Methods)

| 方法名 | 说明 | | --------- | ------------------------------------------ | | reset() | 重置验证码组件,重新加载图片并恢复初始状态 |

使用示例

// 初始化验证码
let captcha = sliderCaptcha({
	id: 'captcha',
});

// 点击刷新按钮时调用
const refresh = () => {
	captcha.reset();
};

服务器端验证

工作原理

客户端在用户完成拖动操作后,会将滑动轨迹数据(trail 数组)发送到服务器进行验证。服务器通过分析轨迹数据的离散程度来判断是否为人为操作——人类拖动过程中会产生自然的 Y 轴抖动,而机器自动化操作的轨迹通常较为规律。

客户端配置

配置 remoteUrlverify 两个选项即可启用服务器端验证:

sliderCaptcha({
	id: 'captcha',
	repeatIcon: 'iconfont iconfont-shuaxin',
	setSrc: function () {
		return 'https://imgs.blazor.zone/images/Pic' + Math.round(Math.random() * 136) + '.jpg';
	},
	onSuccess: function () {
		console.log('验证成功');
	},
	remoteUrl: '/api/Captcha/Verify',
	verify: function (trail, remoteUrl) {
		let result = false;
		$.ajax({
			url: remoteUrl,
			data: JSON.stringify(trail),
			async: false,
			cache: false,
			type: 'POST',
			contentType: 'application/json',
			dataType: 'json',
			success: function (data) {
				result = data;
			},
		});
		return result;
	},
});

参数说明

| 参数 | 类型 | 说明 | | ----------- | -------- | ----------------------------- | | trail | number[] | 客户端拖动滑块的 Y 轴轨迹数组 | | remoteUrl | string | 服务器端验证请求地址 |

服务器端代码示例

.NET Core WebApi

using Microsoft.AspNetCore.Mvc;

[Route("api/[controller]")]
[ApiController]
[AllowAnonymous]
public class CaptchaController : ControllerBase
{
    [HttpPost]
    public bool Verify([FromBody] List<int> trail)
    {
        if (trail == null || trail.Count == 0)
            return false;

        var sum = trail.Sum();
        var avg = sum * 1.0 / trail.Count;
        var stddev = trail.Select(v => Math.Pow(v - avg, 2)).Sum() / trail.Count;

        return stddev != 0;
    }
}

Java Spring Boot

@RestController
@RequestMapping("/sliderCaptcha")
public class SliderCaptchaController {

    @PostMapping("/verify")
    public boolean verify(@RequestBody List<Integer> trail) {
        if (trail == null || trail.isEmpty()) {
            return false;
        }

        int sum = 0;
        for (Integer data : trail) {
            sum += data;
        }
        double avg = sum * 1.0 / trail.size();

        double sum2 = 0.0;
        for (Integer data : trail) {
            sum2 += Math.pow(data - avg, 2);
        }

        double stddev = sum2 / trail.size();
        return stddev != 0;
    }
}

验证算法说明

服务器端验证的核心原理是基于滑动轨迹的方差计算:

  1. 计算平均值:求出轨迹数组所有 Y 轴偏移值的平均值
  2. 计算方差:求出每个值与平均值的偏差的平方和,再除以样本数量
  3. 判断结果:如果方差为 0,说明 Y 轴没有偏移(机器操作),返回 false;如果方差不为 0,说明有人为抖动(人为操作),返回 true

常见问题

Q: 服务器端验证返回结果为什么一直都是 true?

A:示例代码中使用 Y 轴平方差进行校验。当方差为 0 时返回 false,否则返回 true

返回 true 表示 Y 轴存在偏移,系统认为此操作是人为操作。因为人手拖动过程中必然会产生 Y 轴抖动,而机器自动化操作的轨迹理论上不会有 Y 轴偏移。因此可以根据此返回值判断是否为真实用户操作。

Q: 图片加载失败怎么办?

A:组件内置了图片加载容错机制。当远程图片加载失败次数超过 maxLoadCount(默认 3 次)后,会自动调用 localImages 配置的回调函数加载本地备用图片。默认本地图片路径为 images/Pic0.jpgimages/Pic4.jpg

Q: 如何自定义图片源?

A:通过 setSrc 配置项自定义图片加载逻辑:

sliderCaptcha({
	id: 'captcha',
	setSrc: function () {
		return 'https://your-image-server.com/images/' + Math.round(Math.random() * 100) + '.jpg';
	},
});

Q: 验证失败后如何自动重置?

A:组件会在验证失败 1 秒后自动重置。如需手动控制重置,调用 reset() 方法即可。

发布 npm 包

准备工作

  1. 注册 npm 账号:https://www.npmjs.com/signup
  2. 在本地登录 npm:npm login
  3. 确保 package.json 中的包名唯一(当前使用 @sbsbok/slider-captcha

发布流程

# 1. 安装依赖
npm install

# 2. 构建包
npm run build

# 3. 添加npm用户身份(如果没有登录)
npm login

# 4. 发布包(scoped 包需要添加 --access public)
npm publish --access public

版本管理

# 更新补丁版本(1.0.0 -> 1.0.1)
npm version patch

# 更新小版本(1.0.0 -> 1.1.0)
npm version minor

# 更新大版本(1.0.0 -> 2.0.0)
npm version major

发布后验证

# 在项目中测试安装
npm install @sbsbok/slider-captcha

参与贡献

欢迎提交 Issue 和 Pull Request 来帮助改进本项目。

贡献流程

  1. Fork 本项目
  2. 创建功能分支 (git checkout -b feature/AmazingFeature)
  3. 提交更改 (git commit -m 'Add some AmazingFeature')
  4. 推送到分支 (git push origin feature/AmazingFeature)
  5. 创建 Pull Request

许可证

本项目遵循 MIT 许可证。

联系方式

  • 邮箱:[email protected]
  • 项目地址:https://gitee.com/LongbowEnterprise/SliderCaptcha

如有问题或建议,请在 Issue 页面提交。