Vue 利用Canvas标签实现动态验证码校验(前端必备附源码)

朱雀 2023-10-12 15:03 54阅读 0赞

文章目录

  • 一、前言
  • 二、Canvas简介
      • - 什么是Canvas?
      • - Canvas的基本使用
  • 三、动态验证码的具体实现
      • - 在项目中创建 SIdentify.vue 文件
      • - 再创建要使用该组件的文件,App.vue

一、前言

当我们在平时进行登录或者注册账号的时候,往往都会遇到验证动态验证码的情况,当然现在更流行的是一些滑动拼图或者是文字点选,下面我将介绍以下我实现动态验证码的思路。

二、Canvas简介

- 什么是Canvas?

HTML5新增的元素,通过使用脚本语言(JS)来在特定的区域绘制图形,可以制作照片集和简单的动画,也可以处理和渲染视频。

- Canvas的基本使用

  1. <canvas id="myCanvas" width="200" height="100"></canvas>

注意: 标签通常需要指定一个id属性 (脚本中经常引用), width 和 height 属性定义的画布的大小.
提示: 你可以在HTML页面中使用多个 canvas 元素.

通过设置边框使canvas画处理的图形显示出来

  1. <canvas id="myCanvas" width="200" height="100" style="border: 1px solid #000000"> </canvas>

使用JavaScript 来绘制图像

  1. let c = document.getElementById('myCanvas');
  2. let ctx = c.getContext('2d');
  3. ctx.fillStyle = '#FF0000';
  4. ctx.fillRect(0, 0, 150, 75);

这里对canvas进行简单的介绍,大家可以进行系统的学习

三、动态验证码的具体实现

在这里插入图片描述

- 在项目中创建 SIdentify.vue 文件

代码如下

  1. <template>
  2. <div class="s-canvas">
  3. <canvas id="s-canvas" :width="contentWidth" :height="contentHeight" class="canvas"></canvas>
  4. </div>
  5. </template>
  6. <script>
  7. export default {
  8. name: "SIdentify",
  9. props: {
  10. identifyCode: {
  11. type: String,
  12. default: "1234"
  13. },
  14. fontSizeMin: {
  15. type: Number,
  16. default: 35
  17. },
  18. fontSizeMax: {
  19. type: Number,
  20. default: 35
  21. },
  22. backgroundColorMin: {
  23. type: Number,
  24. default: 180
  25. },
  26. backgroundColorMax: {
  27. type: Number,
  28. default: 240
  29. },
  30. colorMin: {
  31. type: Number,
  32. default: 50
  33. },
  34. colorMax: {
  35. type: Number,
  36. default: 160
  37. },
  38. lineColorMin: {
  39. type: Number,
  40. default: 100
  41. },
  42. lineColorMax: {
  43. type: Number,
  44. default: 200
  45. },
  46. dotColorMin: {
  47. type: Number,
  48. default: 0
  49. },
  50. dotColorMax: {
  51. type: Number,
  52. default: 255
  53. },
  54. contentWidth: {
  55. type: Number,
  56. default: 100
  57. },
  58. contentHeight: {
  59. type: Number,
  60. default: 30
  61. }
  62. },
  63. methods: {
  64. // 生成一个随机数
  65. randomNum (min, max) {
  66. return Math.floor(Math.random() * (max - min) + min);
  67. },
  68. // 生成一个随机的颜色
  69. randomColor (min, max) {
  70. let r = this.randomNum(min, max);
  71. let g = this.randomNum(min, max);
  72. let b = this.randomNum(min, max);
  73. return "rgb(" + r + "," + g + "," + b + ")";
  74. },
  75. transparent () {
  76. return "rgb(255,255,255)";
  77. },
  78. drawPic () {
  79. let canvas = document.getElementById("s-canvas");
  80. let ctx = canvas.getContext("2d");
  81. ctx.textBaseline = "bottom";
  82. // 绘制背景
  83. ctx.fillStyle = this.randomColor(
  84. this.backgroundColorMin,
  85. this.backgroundColorMax
  86. );
  87. ctx.fillStyle = this.transparent();
  88. ctx.fillRect(0, 0, this.contentWidth, this.contentHeight);
  89. // 绘制文字
  90. for (let i = 0; i < this.identifyCode.length; i++) {
  91. this.drawText(ctx, this.identifyCode[i], i);
  92. }
  93. //绘制背景
  94. this.drawLine(ctx)
  95. this.drawDot(ctx)
  96. },
  97. drawText (ctx, txt, i) {
  98. ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax);
  99. ctx.font =
  100. this.randomNum(this.fontSizeMin, this.fontSizeMax) + "px SimHei";
  101. let x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1));
  102. let y = this.randomNum(this.fontSizeMax, this.contentHeight - 5);
  103. var deg = this.randomNum(-10, 10);
  104. // 修改坐标原点和旋转角度
  105. ctx.translate(x, y);
  106. ctx.rotate((deg * Math.PI) / 180);
  107. ctx.fillText(txt, 0, 0);
  108. // 恢复坐标原点和旋转角度
  109. ctx.rotate((-deg * Math.PI) / 180);
  110. ctx.translate(-x, -y);
  111. },
  112. drawLine (ctx) {
  113. // 绘制干扰线
  114. for (let i = 0; i < 8; i++) {
  115. ctx.strokeStyle = this.randomColor(
  116. this.lineColorMin,
  117. this.lineColorMax
  118. );
  119. ctx.beginPath();
  120. ctx.moveTo(
  121. this.randomNum(0, this.contentWidth),
  122. this.randomNum(0, this.contentHeight)
  123. );
  124. ctx.lineTo(
  125. this.randomNum(0, this.contentWidth),
  126. this.randomNum(0, this.contentHeight)
  127. );
  128. ctx.stroke();
  129. }
  130. },
  131. drawDot (ctx) {
  132. // 绘制干扰点
  133. for (let i = 0; i < 100; i++) {
  134. ctx.fillStyle = this.randomColor(0, 255);
  135. ctx.beginPath();
  136. ctx.arc(
  137. this.randomNum(0, this.contentWidth),
  138. this.randomNum(0, this.contentHeight),
  139. 1,
  140. 0,
  141. 2 * Math.PI
  142. );
  143. ctx.fill();
  144. }
  145. }
  146. },
  147. watch: {
  148. identifyCode () {
  149. this.drawPic();
  150. }
  151. },
  152. mounted () {
  153. this.drawPic();
  154. }
  155. };
  156. </script>
  157. <style scoped>
  158. .canvas {
  159. margin-top: -0.2667rem;
  160. }
  161. </style>

- 再创建要使用该组件的文件,App.vue

代码如下

  1. <template>
  2. <div class="login container">
  3. <input type="text" placeholder="请输入图片验证码" v-model="imgUrlCode"></input>
  4. <div class="get-code" @click="refreshCode()">
  5. <s-identify :identifyCode="identifyCode"></s-identify>
  6. </div>
  7. </div>
  8. </template>
  9. <script>
  10. import SIdentify from "./components/SIdentify.vue";
  11. export default {
  12. data () {
  13. return {
  14. identifyCode: "",
  15. // 这里是我们验证码的全部元素,生成的验证码由下面的字符串组成,大家可以随意添加
  16. identifyCodes: "0123456789abcdwerwshdjeJKDHRJHKOOPLMKQ",//绘制的随机
  17. // 图片验证码
  18. imgUrlCode: '',
  19. }
  20. },
  21. components: {
  22. //注册组件
  23. SIdentify
  24. },
  25. created () {
  26. this.refreshCode()
  27. },
  28. methods: {
  29. refreshCode () {
  30. // 刷新验证码
  31. this.identifyCode = "";
  32. // 4是控制生成验证码的长度
  33. this.makeCode(this.identifyCodes, 4);
  34. },
  35. randomNum (min, max) {
  36. max = max + 1
  37. return Math.floor(Math.random() * (max - min) + min)
  38. },
  39. // 随机生成验证码字符串
  40. makeCode (data, len) {
  41. for (let i = 0; i < len; i++) {
  42. this.identifyCode += data[this.randomNum(0, data.length - 1)]
  43. }
  44. },
  45. }
  46. }
  47. </script>
  48. <style>
  49. input {
  50. width: 120px;
  51. height: 30px;
  52. }
  53. .container {
  54. display: flex;
  55. justify-content: center;
  56. align-items: center;
  57. }
  58. .get-code {
  59. margin-top: 10px;
  60. width: 80px;
  61. height: 30px;
  62. }
  63. </style>

这里并未对输入的验证码进行验证,大家可以对输入的验证码 imgUrlCode 和 生成的验证码 identifyCodes 进行对比和验证。

欢迎大家在评论区讨论,一起学习

发表评论

表情:
评论列表 (有 0 条评论,54人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Vue实现验证

    在Web应用程序中,为了避免机器自动化或恶意攻击,很常见的做法是要求用户在表单提交之前输入验证码。验证码最常见的形式是图片验证码,因为图片验证码最大程度地防止了自动化机器调用A