全栈开发一条龙——前端篇
第一篇:框架确定、ide设置与项目创建
第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。
第三篇:setup语法,设置响应式数据。
第四篇:数据绑定、计算属性和watch监视
第五篇 : 组件间通信及知识补充
第六篇:生命周期和自定义hooks
第七篇:路由
第八篇:传参
第九篇:插槽,常用api和全局api。
全栈开发一条龙——全栈篇
第一篇:初识Flask&MySQL实现前后端通信
第二篇: sql操作、发送http请求和邮件发送
上次我们实现了发邮件,这次我们来实现一个场景:发送随机验证码,限时5分钟,通过才能注册账号。本文将一步步展开实现这个小功能。
先配置好redis库:参考资料使用zip安装方式更加方便快捷。
文章目录
- 后端
- 一、生成随机验证码
- 二、保存验证码
- 三、验证邮箱&蓝图创建
- 四、功能整合
- 前端
- 入口文件
- 实现组件
- 开放局域网端口
- 验证码验证和数据库操作
后端
一、生成随机验证码
要实现随机验证码,我们先引入python自带的random
def random_code(pure_num = True):
if pure_num == True:
rand_temp = random.randint(100000,999999)
rand_str = str(rand_temp)
else:
base_str = "0123456789qwertyuiopasdfghjklzxcvbnm"
rand_str=""
for _ in range(6):
rand_str += random.choice(base_str)
return rand_str
我们首先加入一个判断,需要的随机序列是否需要是纯数字,如果是我们就生成一个6位数,然后转化为str。如果不是纯数字,我们先写一个选择序列,就是所有数字和字母的字符串,然后用随机函数抽取,添加到我们的结果字符串中,最后返回。
注意不要忘记给rand_str赋初值,不然不能用rand_str += xxx.
有很多人喜欢写列表推导式
性能确实不错,但如果你是我同事,我也略懂一些拳脚。
二、保存验证码
我们首先进入data文件,配置以下redis数据库对象
import redis
rd = redis.Redis(decode_responses=True)
然后我们去业务文件mail_send.py中进行缓存操作。
from data import rd
先导入redis对象
然后用原子操作设定数据对应关系和缓存时间
def save_random_code(email,code,lifelong=300):
error_ju = rd.setex(email,lifelong,code)
#返回是否保存成功
return error_ju
第二行代码 参数分别是 key 周期 value
周期就是数据存在的时间,单位是s,此处就是数据存在5分钟。
save_random_code(email="scls@qq.com", code=random_code() , lifelong=50)
测试一下,打开redis的cli界面,发现是存储成功的
过了我设置的50秒lifelong之后再次查询
发现缓存消失了。
redis-cli的语句有如下几句,各位可以自行测试:
ttl key 看剩下的生命周期
get key 查看数据
keys * 查看有哪些key
三、验证邮箱&蓝图创建
接下来,我们准备进入发送验证邮件的步骤了,我们首先要验证邮箱的合法性
import re
def is_valid_email(email):
ex_email = re.compile(r'^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$')
#匹配正则
res = ex_email.match(email)
return bool(res)
这里正则看不懂没关系,正常业务中都是直接上网查的。此处就是保证一下邮箱的基本格式,然后我们在发邮件,用验证码的方式判断邮箱是否是真实的。
我们为这个发邮件功能专门写一个蓝图(为了方便管理,事实上就是解耦合、对象封装的思想)
from flask import Blueprint,jsonify,request
from flask.views import MethodView
from data import db,rd
from mail_send import is_valid_email
user_view = Blueprint("user_view",__name__)
class code_sending_verify(MethodView):
def get(self):
email = request.args.get("email",None)
if not email:
return jsonify( {"errcode":1,"msg":"缺失邮箱"} )
if not is_valid_email(email=email):
return jsonify( {"errcode":2,"msg":"邮箱不合法"} )
return jsonify( {"errcode":0,"msg":"发送成功"} )
#配置类视图
user_view.add_url_rule("/sendcode/",view_func=code_sending_verify.as_view("code_sending_verify") )
然后再manage中注册蓝图
from user_verify import user_view
app.register_blueprint(user_view)
这样我们就为/sendcode/路由加上功能了。
然后我们用test尝试是否有bug
res = httpapi.test_get("http://localhost:5000/sendcode/",data={"email":"123123@163.com"})
res = res.encode('utf-8').decode('unicode_escape')
print(res)
四、功能整合
最后,我们将功能整合,通过get方式访问这个路径就可以完成以下逻辑:
如果传入了一个有效邮箱,那就发送验证码并保存,不然就抛出那一步遇到问题。
from flask import Blueprint,jsonify,request
from flask.views import MethodView
from data import db,rd
from mail_send import is_valid_email,send_email,random_code,save_random_code
user_view = Blueprint("user_view",__name__)
class code_sending_verify(MethodView):
def get(self):
# 传入邮箱
email = request.args.get("email",None)
if not email:
return jsonify( {"errcode":1,"msg":"缺失邮箱"} )
if not is_valid_email(email=email):
return jsonify( {"errcode":2,"msg":"邮箱不合法"} )
mail = send_email()
verify_code = random_code()
mail.send_mail(dest_mail=email,title="验证码",content=verify_code)
correctly_save = save_random_code(email=email,code=verify_code,lifelong=180)
if not correctly_save:
return jsonify( {"errcode":3,"msg":"保存失败"} )
return jsonify( {"errcode":0,"msg":"发送成功"} )
#配置类视图
user_view.add_url_rule("/sendcode/",view_func=code_sending_verify.as_view("code_sending_verify") )
前端
入口文件
下载阿里的组件库,这用就不用你亲自写样式,非常方便
npm install antd
注:如果以下内容有提示报错,请去env.d.ts中加入declare module '*.vue’就好了
import testapi from '@/components/API1.vue'
先把app(前端入口文件写好)
<template>
<testapi/>
</template>
<script setup name="app">
import testapi from '@/components/API1.vue'
</script>
<style>
</style>
然后我们主要写组件。
实现组件
style中是样式,可以网上直接找的,不再多说。
说说思路,我们现在上方添加一个输入框,用于输入邮箱,然后将这个数据绑定给email。
然后我们写一个按钮,这个按钮绑定一个方法,点击之后,将email传给我们刚刚发邮箱的后端代码。
然后接收返回值,打印到控制台上方便调试
我们的axios是用来方便我们发送方http请求的,是第三方库,使用很便捷,输入npm i axios就可以安装了。
alert方法是window.alert方法的简写,可以用来唤出提示框
window还有许多很好用的方法和属性,这里附上中文说明window详细说明
完整代码如下:
<template>
<div>
<!-- <input type="text" name="text" placeholder="请输入你的注册id" class="input" v-model="user_id"> -->
<input type="text" name="text" placeholder="请输入你的注册邮箱" class="input" v-model="email">
<!-- <input type="text" name="text" placeholder="请输入你的用户名" class="input" v-model="name">
<input type="text" name="text" placeholder="请输入你的密码" class="input" v-model="pwd"> -->
<button @click="send_mail">
<div class="svg-wrapper-1">
<div class="svg-wrapper">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
width="115"
height="24"
>
<path fill="none" d="M0 0h24v24H0z"></path>
<path
fill="currentColor"
d="M1.946 9.315c-.522-.174-.527-.455.01-.634l19.087-6.362c.529-.176.832.12.684.638l-5.454 19.086c-.15.529-.455.547-.679.045L12 14l6-8-8 6-8.054-2.685z"
></path>
</svg>
</div>
</div>
<span>Send</span>
</button>
</div>
<!--
<div>
<h3>{{ user_id }}</h3>
<h3>{{ email }}</h3>
<h3>{{ name }}</h3>
<h3>{{ pwd }}</h3>
</div> -->
</template>
<script setup name="testapi">
import { ref } from 'vue';
import axios from 'axios';
let user_id =ref("")
let email =ref("")
let name =ref("")
let pwd =ref("")
async function send_mail(){
try{
let result=await axios.get('http://127.0.0.1:5000/sendcode/',{params:{email:email.value}})
if(result.data.errorcode != 0)
{window.alert(result.data.msg)}
console.log(result.data)
} catch(error){alert(error)}
}
</script>
<style>
/* id */
.input[type = "text"] {
display: block;
color: rgb(34, 34, 34);
background: linear-gradient(142.99deg, rgba(217, 217, 217, 0.63) 15.53%, rgba(243, 243, 243, 0.63) 88.19%);
box-shadow: 0px 12px 24px -1px rgba(0, 0, 0,0.18);
border-color: rgba(7, 4, 14, 0);
border-radius: 50px;
block-size: 20px;
margin: 7px auto;
padding: 18px 15px;
outline: none;
text-align: center;
width: 200px;
transition: 0.5s;
}
.input[type = "text"]:hover {
width: 240px;
}
.input[type = "text"]:focus {
width: 280px;
}
/* id */
/* button_send */
button {
font-family: inherit;
font-size: 20px;
background: royalblue;
color: white;
padding: 0.7em 1em;
padding-left: 0.9em;
display: flex;
align-items: center;
border: none;
border-radius: 16px;
overflow: hidden;
transition: all 0.2s;
cursor: pointer;
}
button span {
display: block;
margin-left: 0.3em;
transition: all 0.3s ease-in-out;
}
button svg {
display: block;
transform-origin: center center;
transition: transform 0.3s ease-in-out;
}
button:hover .svg-wrapper {
animation: fly-1 0.6s ease-in-out infinite alternate;
}
button:hover svg {
transform: translateX(1.2em) rotate(45deg) scale(1.1);
}
button:hover span {
transform: translateX(5em);
}
button:active {
transform: scale(0.95);
}
@keyframes fly-1 {
from {
transform: translateY(0.1em);
}
to {
transform: translateY(-0.1em);
}
}
/* button_send */
</style>
开放局域网端口
我们用 npm run dev -- --host 0.0.0.0 --port 5173
来启动我们的前端服务,然后把我们刚刚写好的访问后端的网址改成后端的服务端口
可以在我们启动后端服务的地方看到
之后我们的前端服务会跳出来我们可以访问的局域网网址,在手机上也可以访问哦~
验证码验证和数据库操作
我们先在api中再加入一个按钮,绑定一个方法
async function verify_code(){
try{
let result=await axios.get('http://127.0.0.1:5000/verify_code/',{params:{
email:email.value,
code:verify_code_txt.value,
id:user_id.value,
password:pwd.value,
name : name.value}})
window.alert(result.data.msg)
} catch(error){
alert(error)
}
}
跟之前一样,讲数据传递给后端进行验证
class verify_code(MethodView):
#验证验证码
def get(self):
email=request.args.get("email",None)
id=request.args.get("id",None)
name=request.args.get("name",None)
password=request.args.get("password",None)
verify_code = request.args.get("code",None)
print(email,id,name,password,verify_code,"\n\n\n\n")
saved_code = rd.get(email)
if not saved_code:
return jsonify( {"errcode":5,"msg":"未向该邮箱发送验证码或超时"} )
if saved_code != verify_code:
return jsonify( {"errcode":6,"msg":"验证码错误"} )
res = test_post("http://localhost:5000/insert/",data={"id":id,"name":name,"email":email,"password":password})
return jsonify( {"errcode":0,"msg":"注册成功"} )
user_view.add_url_rule("/verify_code/",view_func=verify_code.as_view("verify_code") )
我们先判断,如果验证码是一样的,拿我们就调用之前写好的加入数据库的接口。
进入mysql中查看
添加成功~