验证码——vue中后端返回的图片流如何显示
目录
前言
一、p调用接口获取验证码 + canvas画布渲染?
二、后端返回图片(图片流),前端显示
1.blob
2.arraybuffer
总结
前言
登录界面经常会有验证码,验证码的实现方式也有很多,我目前做过以下两种:
1.调用接口获取验证码 + canvas画布渲染
2.后端返回图片(数据流),前端显示
这两种方式都比较简单,本次项目技术栈为:vue2.6 + axsio ,接下来一起看看把~
一、p调用接口获取验证码 + canvas画布渲染?
这个比较简单,就是需要自己写一份canvas ,将后端获取过来得验证码显示出来,后续将验证码和识别码一起传递给后端,后端校验账户密码验证码是否一致。
1.编写canvas组件
这里我把他写成一个组件
<template><div class="s-canvas" id="canvas"><canvas id="s-canvas"></canvas></div>
</template><script>
export default {name: 'SIdentify',data() {return {w: '',h: '',}},props: {identifyCode: {type: String,default: '1234',},fontSizeMin: {type: Number,default: 26,},fontSizeMax: {type: Number,default: 30,},backgroundColorMin: {type: Number,default: 255,},backgroundColorMax: {type: Number,default: 255,},colorMin: {type: Number,default: 0,},colorMax: {type: Number,default: 160,},lineColorMin: {type: Number,default: 100,},lineColorMax: {type: Number,default: 255,},dotColorMin: {type: Number,default: 0,},dotColorMax: {type: Number,default: 255,},contentWidth: {type: Number,default: 121,},contentHeight: {type: Number,default: 50,},},methods: {//计算外盒子高度boxSize() {var contanier = document.getElementById('canvas')var canvas = document.getElementById('s-canvas')console.log(canvas, 'canvas')canvas.width = contanier.offsetWidthcanvas.height = contanier.offsetHeightthis.w = contanier.offsetWidththis.h = contanier.offsetHeightconsole.log(this.w, this.h, '获取到得canvas宽高')},// 生成一个随机数randomNum(min, max) {return Math.floor(Math.random() * (max - min) + min)},// 生成一个随机的颜色randomColor(min, max) {let r = this.randomNum(min, max)let g = this.randomNum(min, max)let b = this.randomNum(min, max)return 'rgb(' + r + ',' + g + ',' + b + ')'},drawPic() {let canvas = document.getElementById('s-canvas')let ctx = canvas.getContext('2d')ctx.textBaseline = 'bottom'// 绘制背景ctx.fillStyle = this.randomColor(this.backgroundColorMin,this.backgroundColorMax)// console.log(this.contentWidth,this.contentHeight,"图形大小")ctx.fillRect(0, 0, this.w, this.h)// 绘制文字for (let i = 0; i < this.identifyCode.length; i++) {this.drawText(ctx, this.identifyCode[i], i)}this.drawLine(ctx)this.drawDot(ctx)},drawText(ctx, txt, i) {ctx.fillStyle = this.randomColor(this.colorMin, this.colorMax)ctx.font =this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei'let x = (i + 1) * (this.w / (this.identifyCode.length + 1))let y = this.randomNum(this.fontSizeMax, this.h - 5)var deg = this.randomNum(-45, 45)// 修改坐标原点和旋转角度ctx.translate(x, y)ctx.rotate((deg * Math.PI) / 180)ctx.fillText(txt, 0, 0)// 恢复坐标原点和旋转角度ctx.rotate((-deg * Math.PI) / 180)ctx.translate(-x, -y)},drawLine(ctx) {// 绘制干扰线for (let i = 0; i < 5; i++) {ctx.strokeStyle = this.randomColor(this.lineColorMin, this.lineColorMax)ctx.beginPath()ctx.moveTo(this.randomNum(0, this.contentWidth),this.randomNum(0, this.contentHeight))ctx.lineTo(this.randomNum(0, this.contentWidth),this.randomNum(0, this.contentHeight))ctx.stroke()}},drawDot(ctx) {// 绘制干扰点for (let i = 0; i < 80; i++) {ctx.fillStyle = this.randomColor(0, 255)ctx.beginPath()ctx.arc(this.randomNum(0, this.contentWidth),this.randomNum(0, this.contentHeight),1,0,2 * Math.PI)ctx.fill()}},},watch: {identifyCode() {this.drawPic()},},created() {},mounted() {this.boxSize()this.drawPic()},
}
</script><style lang="stylus" scoped>
.s-canvas {width: 121pxheight: 50px;}
</style>
2.使用组件
引入该组件并命名为identifyCode
import IdentifyCode from '@/components/identifyCode'
<Identify-code :identifyCode="identifyCode"></Identify-code>
初始化得时候获取后端返回得验证码
created(){
this.getCode()
}
//获取验证码
async getCode() {try {await XX().then((res) => {this.identifyCode = res})} catch (err) {console.log(err)}}
二、后端返回图片(图片流),前端显示
首先我们明确两个点:
- 普通请求接收的时候是json格式,图片流的接收模式可选两种:blob和arraybuffer。
- blob和arraybuffer本质上都是二进制数据。如果使用blob我们只需要用 window.URL.createObjectURL(res)就可以得到图片链接;如果使用arraybuffer,我们需要将其转为base64的格式。
好啦,下面就开始啦~
首先我们先设置标签变量,如下:
<div class="getCaptcha" @click="getimgCaptcha()"><img:src="codeImg"style="width:135px;height:40px;"title="看不清,点击换一张"loading="lazy"alt="点击重新获取验证码"srcset="">
</div>
1.blob
请求设置,代码如下:
export function getCaptcha () {return request({url: /getCaptcha,method: 'get',responseType: 'blob' //选择接收方式为blob})
}
图片处理,代码如下:
getCaptcha (e) {getCaptcha().then(res => {this.codeImg = window.URL.createObjectURL(res) // 这里调用window的URL方法console.log(this.codeImg, '地址')}).catch(err => {console.log(err)})},
2.arraybuffer
请求设置,代码如下:
// 图片验证码
export function getCaptcha () {return request({url: /getCaptch,method: 'get',responseType: 'arraybuffer'})
}
图片处理,代码如下:
getCaptcha (e) {getCaptcha().then(res => {//1. btoa表示 base64转ASCII ,对应的还有 atob 表示 ASCII转base64//2. Unit8Arrat() 是arraybuffer里面的一种类型const url = 'data:image/png;base64,' + btoa(new Uint8Array(res).reduce((data, byte) => data + String.fromCharCode(byte), ''))this.codeImg = urlconsole.log(this.codeImg, '地址')}).catch(err => {console.log(err)})},
关于blod和arraybuffer的区别和具体用法,参考:前端二进制学习(三)
当然还有其它的二进制流,向上传文件或图片的时候用到的:File、FileReader、FormData,感兴趣可以自己去了解一下。
总结
以上就是今天要讲的内容,本文仅仅简单两种验证码的实现方式,当然还有其他的验证吗实现方式,感兴趣自己去看看把~
相关文章:
验证码——vue中后端返回的图片流如何显示
目录 前言 一、p调用接口获取验证码 canvas画布渲染? 二、后端返回图片(图片流),前端显示 1.blob 2.arraybuffer 总结 前言 登录界面经常会有验证码,验证码的实现方式也有很多,我目前做过以下两种&…...
聚观早报 | 拼多多驳斥Google的指控;80%美国人工作将被AI影响
今日要闻:拼多多驳斥Google“恶意软件”的指控;80%美国人工作将被AI影响;iPhone 15 Pro设计图上热搜;贾扬清离职阿里投身AI大模型创业;OPPO Find X6 系列发布拼多多驳斥Google“恶意软件”的指控 3 月 21 日࿰…...
define,typedef,inline 的区别
define 1.用于在代码中创建宏定义,将一个标识符替换为一个表达式或语句。例如: #define PI 3.14159 #define SQUARE(x) ((x) * (x))这样,程序中所有出现的 PI 都将被替换为 3.14159,SQUARE(x) 则被替换成了 (x) * (x)。 使用 #…...
百度文心一言正式亮相
OpenAI 刚发布了 GPT-4,百度预热已久的人工智能生成式对话产品也终于亮相了。昨天下午,文心一言 (ERNIE Bot)—— 百度全新一代知识增强大语言模型、文心大模型家族的新成员,正式在百度总部 “挥手点江山” 会议室里发布。 发布会一开场&…...
使用Android架构模板
使用Android架构模板 项目介绍 为了方便开发者引入最新的Android架构组建进行开发,Google官方给我们引入了一个架构模板,方便我们快速进入开发。 github地址: https://github.com/android/architecture-templates 该模板遵循官方架构指南 …...
2023年天津市逆向re2.exe解析-比较难(超详细)
2023年天津市逆向re2.exe解析(较难) 1.拖进IDA里进行分析2.动态调试3.编写EXP脚本获取FLAG4.获得FLAG1.拖进IDA里进行分析 进入主程序查看伪代码 发现一个循环,根据行为初步判定为遍历输入的字符并对其ascii^7进行加密 初步判断sub_1400ab4ec为比较输入和flag的函数 跟进u…...
springboot: mybatis动态拼接sql查询条件
目录 需求01: 根据不同类型 查询不同的订单名, 1. 书写订单 类型转换方法 2. 使用方式: 3.. 构建条件构造器并进行查询, 传递查询参数 4. Mapper 写法 5. 最核心位置 xml位置 6. sql执行效果: 需求01: 根据不同类型 查询不同的订单名, 条件也是不同的, 需要复用sql…...
最优化算法 - 动态规划算法
动态规划算法简介 动态规划(Dynamic programming)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题…...
springCloud学习【3】之Docker(1)
文章目录一 Docker环境准备1.1 应用部署的环境问题1.2 Docker简介1.3 Docker解决操作系统环境差异1.4 Docker和虚拟机的区别1.5 Docker架构1.5.1 镜像和容器1.5.2 DockerHub1.5.3 Docker架构1.5.4 Docker工作流1.6 Docker的安装和启动1.7 安装步骤1.8 启动Docker1.9 配置镜像加…...
难以置信,已经有人用 ChatGPT 做 Excel 报表了?
要问2023年初科技领域什么最火,那自然是 ChatGPT。 ChatGPT 由人工智能研究实验室 OpenAI 于2022年11月30日推出。上线短短5天,用户数量已突破100万,在今年2月份,用户数量已经突破1亿。 ChatGPT 是一个超级智能聊天机器人&#…...
中断相关操作函数HAL_NVIC_SetPriority()、HAL_NVIC_EnableIRQ()
文章目录HAL_NVIC_SetPriority():设置中断优先级HAL_NVIC_EnableIRQ():使能中断结束HAL_NVIC_SetPriority():设置中断优先级 HAL_NVIC_SetPriority()函数是一个用于设置中断优先级的函数,其定义如下: void HAL_NVIC_…...
企业增长秘诀丨设立优质的帮助中心,加深用户产品使用深度,促进产品转化
客户的留存问题一直备受企业关注,留存率的高低反应了产品的真实状况,将直接影响企业后期的发展规划。下文将为大家剖析下产品中客户的转化流程,以及如何提高产品的使用深处与复购率。 产品中,从客户生命周期角度,可分…...
3.OSPF与BGP的联动
14.3实验3:OSPF与BGP联动配置 实验目的实验拓扑实验步骤 配置IP地址 AR1的配置 <Huawei>system-view Enter system view, return user view with CtrlZ. [Huawei]undo info-center enable Info: Information center is disabled. [Huawei]sysname AR1 …...
机器学习算法——决策树详解
文章目录前言:决策树的定义熵和信息熵的相关概念信息熵的简单理解经典的决策树算法ID3算法划分选择或划分标准——信息增益ID3算法的优缺点C4.5算法信息增益率划分选择或划分标准——Gini系数(CART算法)Gini系数计算举例CART算法的优缺点其他…...
配置Jenkins
目录 一.前言 1.1简介 1.2工作步骤图 二.配置jenkins部署项目 2.1项目新建 2.2jenkinsfile文件如下 三.jenkins工作台配置 3.1.点击新建item进入新建页面,输入任务名称,选择pipeline 3.2.选择第二个配置 3.4将ideal中jenkinsfile文件的路径粘入脚本路径中 3.5启动项目…...
【STL三】序列容器——array容器
【STL三】序列容器——array一、array简介二、头文件三、模板类四、成员函数1、迭代器2、元素访问3、容量4、操作五、demo1、容量(不使用迭代器)2、使用迭代器3、元素访问 at()、front()、back()、data()一、array简介 array 容器是 C 11 标准中新增的序…...
【STL四】序列容器——vector容器
【STL容器】序列容器——vector容器一、简介二、头文件三、模板类四、成员函数1、迭代器2、元素访问3、容量4、修改操作五、demo1、容量reserve、capacity、shrink_to_fit2、修改操作pop_back()、push_back3、修改操作insert()4、修改操作emplace()5、修改操作erase()、swap()、…...
4年功能测试,我一进阶python接口自动化测试,跳槽拿了20k......
目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 很多人在这求职市场…...
基于Pytorch的可视化工具
深度学习网络通常具有很深的层次结构,而且层与层之间通常会有并联、串联等连接方式。当使用PyTorch建立一个深度学习网络并输出文本向读者展示网络的连接方式是非常低效的,所以需要有效的工具将建立的深度学习网络结构有层次化的展示,这就需要…...
XCPC第十一站,带你学会图论基本算法
我们约定:以下n表示点的数目,m表示边的数目。 引子1——邻接表存储图的方法()(暂时不考虑重边和自环) 现在我们有n个点(编号为1~n)和m条边,要用数组存储它们,…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
