<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>web前端生成校验码</title>
</head>
<style>
canvas {
width: 100%;
height: 100%;
}
#codeImg {
cursor: pointer;
vertical-align: top;
}
#reset {
cursor: pointer;
}
</style>
<body>
<h1>前端 js 生产验证码</h1>
<div>
<div style="margin-bottom: 20px">
<img id="codeImg" class="code" onclick="showCode()" alt="校验码图" />
<span id="reset" onclick="showCode()">看不清换一张</span>
</div>
<div>
<span>验证码:</span>
<input type="text" id="inputCode" />
</div>
<div style="margin-bottom: 20px">
<button onclick="validateCode()">确定</button>
</div>
</div>
<script>
// 页面加载完成时,生成随机验证码
window.onload = function() {
showCode();
};
// 窗口大小调整时,重新生成校验码
// window.onresize = function() {
// showCode();
// };
// 展示验证码:将验证码赋值到dom的image上
function showCode() {
let image = document.getElementById("codeImg");
let obj = drawCode();
image.src = obj.base64;
console.log("showCode");
console.log(obj.text);
window.sessionStorage.setItem("text", obj.text);
}
// 校验验证码的正确性
function validateCode() {
let inputCode = document.getElementById("inputCode").value.toUpperCase();
let text = window.sessionStorage.getItem("text").toUpperCase();
if (inputCode === text) {
alert("正确");
} else {
alert("错误");
}
}
// 绘制验证码
function drawCode() {
// 校验码的组成库,我们去掉了大小写的字母Oo,因为有0了。
let nums = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
"M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"
],
text = "";
// 创建 canvas 画布,并设置宽高
let canvas = document.createElement("canvas");
canvas.width = 98;
canvas.height = 45;
// 获取画布2D上下文
let context = canvas.getContext("2d");
// 画布填充色
context.fillStyle = "#00BEFD";
// 清空画布
context.fillRect(0, 0, canvas.width, canvas.height);
// 设置字体颜色
context.fillStyle = "white";
// 设置字体
context.font = "25px Microsoft YaHei";
let rand = [], x = [], y = [];
// 绘制校验码到画布上
for (let i = 0; i < 4; i++) {
rand.push(rand[i]);
rand[i] = nums[Math.floor(Math.random() * nums.length)];
x[i] = i * 20 + 10;
y[i] = Math.random() * 20 + 20;
context.fillText(rand[i], x[i], y[i]);
}
// 画2条随机线,可以根据需要增减,画随机线主要是为了提高识别难度,防范机器识别
for (let i = 0; i < 2; i++) {
drawline(canvas, context);
}
// 画20个随机点,随机点的意义同随即线
for (let i = 0; i < 20; i++) {
drawDot(canvas, context);
}
// canvas 生成 image
let base64 = convertCanvasToImage(canvas);
// 校验码的值,将字符串转换为大写,用户填写的校验码不区分大小写
text = rand.join("").toUpperCase();
return { base64: base64, text: text };
}
// 画随机线函数
function drawline(canvas, context) {
// 随机线的起点x坐标是画布x坐标0位置,y坐标是画布高度的随机数
context.moveTo(Math.floor(Math.random() * canvas.width), Math.floor(Math.random() * canvas.height));
// 随机线的终点x坐标是画布宽度,y坐标是画布高度的随机数
context.lineTo(Math.floor(Math.random() * canvas.width), Math.floor(Math.random() * canvas.height));
// 线条的款
context.lineWidth = 0.5;
// 线条的描边属性:颜色透明度
context.strokeStyle = "rgba(50,50,50,0.3)";
// 在画布上画线
context.stroke();
}
// 画随机点函数
function drawDot(canvas, context) {
let px = Math.floor(Math.random() * canvas.width),
py = Math.floor(Math.random() * canvas.height);
context.moveTo(px, py);
context.lineTo(px + 1, py + 1);
context.lineWidth = 0.1;
context.stroke();
}
// 绘制图片,返回 base64 图片
function convertCanvasToImage(canvas) {
try {
return canvas.toDataURL("image/png");
} catch (e) {
console.error("该浏览器版本不支持:canvas.toDataURL(\"image/png\")");
}
}
</script>
</body>
</html>