接上面完成验证码按钮的倒计时按钮形,如下面的形式
在这其中,我们在用jquery绑定对象后就可以获取到按钮标签,在给按钮绑定点击事件,然乎就可以根据点击事件发生后,获取邮箱账号,并通过**$.ajax({})**请求来完成向服务器
function bindEmailCaptcha()
{
// $("#captcha-btn")//#代表id 所以表示为找到id = captcha-btn的标签,再给这个标签绑定一个点击事件click 点击时会执行click里面的函数
$("#captcha-btn").click(function (event)//点击是个事件event,事件发生的位置,针对什么元素等等信息全部放在event事件中
{
var $this=$(this);
event.preventDefault();//阻止 点击发送验证码就提交表单数据
//var email = $('#exampleInputEmail1').val(); //通过id获取
var email= $("input[name='email']").val();//获取到了邮箱的input的标签 然后val就可以获取input标签的值
//alert(email)
$.ajax({
url:"captcha/email?email="+email,
method:'GET',
success:function (result){
code = result['code']
if (code == 200)
{
var countdown = 5;
var timer = setInterval(function ()
{
$this.text(countdown);
countdown-=1;
if (countdown<=0){
clearInterval(timer);
$this.text("获取验证码");
bindEmailCaptcha();
}
},1000)
}
else{
alert("youxiangfasonghshibai")
}
//result 是后端auth.py邮箱获取邮箱验证码的返回值
},
fail:function (error){
console.log(error)
}
});
});
}
这里会向服务器发送ajax请求,携带着参数url,method,success,和fail四个参数
AJAX 请求中的参数,如 url、method、success 和 fail,用于配置发送到服务器的请求。url 参数指定发送请求的 URL,method 参数指定用于请求的 HTTP 方法。success 和 fail 参数是回调函数,分别在请求成功或失败时执行。
其中服务器接收到url参数后,会根绝参数地址,去执行该地址对应的代码功能,(在这里即是发送验证码,并且存储验证码和邮箱账号)。这里method 是get方法,因为flask默认是用get方法的(get方法是把参数放到网页连接处通过?方式来的,post是把数据放到了head里面
??),第三个success,就是在你向服务器成功发送请求后,服务器响应 AJAX 请求返回的数据(就是这里的result)作为参数传递给 success 回调函数。第四个fail,就是在ajax向服务器发送请求的过程中出现错误i了,就会调用fail函数
然后就是在ajax请求成功发送后,编写动态时间变化
其中setInterval就是设定定时器
setInterval接受两个参数一个是函数function(),一个是时间time单位毫秒
就是每隔time时间就执行传递给setInterval的函数
这样就完成了时间倒计时功能。
然后因为又得把按钮内容变成验证码,还得把按钮和点击事件绑定(在倒计时时,我们把按钮和点击事件解除了),这又回到了第一步将事件和点击按钮绑定,所以我们可以把将事件和点击按钮绑定到验证码倒计时结束这整个过程封装成一个函数,这样最终代码就像下面形式
function bindEmailCaptcha()
{
// $("#captcha-btn")//#代表id 所以表示为找到id = captcha-btn的标签,再给这个标签绑定一个点击事件click 点击时会执行click里面的函数
$("#captcha-btn").click(function (event)//点击是个事件event,事件发生的位置,针对什么元素等等信息全部放在event事件中
{
var $this=$(this);
event.preventDefault();//阻止 点击发送验证码就提交表单数据
//var email = $('#exampleInputEmail1').val(); //通过id获取
var email= $("input[name='email']").val();//获取到了邮箱的input的标签 然后val就可以获取input标签的值
//alert(email)
$.ajax({
url:"captcha/email?email="+email,
method:'GET',
success:function (result){
code = result['code']
if (code == 200)
{
var countdown = 5;
var timer = setInterval(function ()
{
$this.text(countdown);
countdown-=1;
if (countdown<=0){
clearInterval(timer);//运行了五秒,为了关闭计时就得clearInterval(timer)
$this.text("获取验证码");
bindEmailCaptcha();
}
},1000)
}
else{
alert("youxiangfasonghshibai")
}
//result 是后端auth.py邮箱获取邮箱验证码的返回值
},
fail:function (error){
console.log(error)
}
});
});
}
$(function ()//整个网页加载完成后才执行这个函数
{
bindEmailCaptcha();
});
最后看看效果
接下来我们只需要把数据库的账号和验证码匹配上,然后将账号,密码存储在数据库中,在再次登陆后检索数据库,就可以完成注册登录页面了。
每天坚持发布自学blog,这为了更好的监督自己
表单验证(验证) 需要flask-wtf(wtfs插件)
pip install flask-wtf
1.编写注册表单
import wtforms
from wtforms.validators import Email,EqualTo,Length
# Form 主要用来验证前端提交的数据是否符合要求
class RegisterForm(wtforms.Form):
email = wtforms.StringField(validators=[Email(message='邮箱格式错误!')])
captcha = wtforms.StringField(validators=[Length(min = 4,max = 4,message = '验证码输入错误!')])
username = wtforms.StringField(validators=[Length(min= 2,max = 20,message='用户名错误!')])
password = wtforms.StringField(validators=[Length(min = 2,max = 20,message="密码格式错误!")])
password_confirm = wtforms.StringField(validators=[EqualTo('password')])
其中这里表单验证就是从前端获取各个表单的数据(符合格式的数据)
#我们也可以用jquery就像获取qq邮箱一样,来获取各个表单,但这个就得一一找到input对应的id然后获取
我们获取到了前端表单的数据,就得和后端数据库数据进行比对
这其中有两个问题我们需要去处理,
- 1.就是邮箱已经被注册了,我们需要弹出,已近完成注册
- 2就是验证码是否正确的问题
1.就是邮箱已经被注册了,我们需要弹出,已近完成注册
def validate_email(self,field): #//验证是否已经注册了
email = field.data
user = UserModel.query.filter_by(email=email).first()
print(type(user))
if user:
raise wtforms.ValidationError(message='该邮箱已经被注册了')#这里的抛出错误页面信息,必须是在前端页面展示的
2就是验证码是否正确的问题
# 2.验证码是否正确 注这里field是传过来的参数 就是上面的email captcha,username,password之类的
def validate_captcha(self,field):#这里是表单*类*的验证验证码的函数,所以self代表表单对象
captcha = field.data
# EmailCaptchaModel.query.filter_by(captcha)
email = self.email.data# 最终获得表单的email的data
captcha_model = EmailCaptchaModel.query.filter_by(email = email,captcha = captcha).first()
if not captcha_model:
raise wtforms.ValidationError(message='验证码输入错误!')
# else: 最好写个脚本,定期的清理一次
# #to da 删除验证码
# db.session.delete(captcha)
# db.session.commit()
到此,我们就完成了自定义验证的编写
2.后端注册表单的实现
我们在register.html要渲染注册页面,然后在所有数据提交完成之后,我们得把表单数据提交给服务器,就是auth/register浏览器页面上也就是register的视图函数,所以我们要如何区分服务器是接受用户提交上来的数据,还是徐要绚烂模板呢,这个时候,我们采用method来区分这两个过程
- GET 就是从服务器获取数据
- PSOT 将客户端数据提交给服务器
当访问auth/register页面,得展示出注册页面,那就是从服务器获取数据
当提交表单后,就是客户端向服务器提交数据
- 表单元素都在form标签中,所以我们可以仅仅用request.form就可以拿到提交给服务器的表单元素。
对于注册的整体逻辑
首先这里先是默认的GET方法可以正常把注册页面渲染出来
@bp.route('/register',methods=['GET','POST'])
def register():
if request.method == 'GET':
return render_template("register.html")# 要导入render_template就可以使用渲染
else:
form = RegisterForm(request.form) #得到一个/RegisterForm对象
if form.validate():
email = form.email.data
password = form.password.data
username = form.username.data
user = UserModel(email = email,password = password,username= username)
db.session.add(user)
db.session.commit()
return 'success in saving mysql'
else:
print(form.errors)
return 'errors'
可以看到下面的渲染出来的页面
接着就是验证码的获取,通过写js代码(页面动态变化和获取前端页面的数据)这个是通过前端javascript和ajax方法向服务器发送请求来完成发送验证码和邮箱号放入数据库表email_captcha中
function bindEmailCaptcha()
{
// $("#captcha-btn")//#代表id 所以表示为找到id = captcha-btn的标签,再给这个标签绑定一个点击事件click 点击时会执行click里面的函数
$("#captcha-btn").click(function (event)//点击是个事件event,事件发生的位置,针对什么元素等等信息全部放在event事件中
{
var $this=$(this);
event.preventDefault();//阻止 点击发送验证码就提交表单数据
//var email = $('#exampleInputEmail1').val(); //通过id获取
var email= $("input[name='email']").val();//获取到了邮箱的input的标签 然后val就可以获取input标签的值
//alert(email)
$.ajax({
url:"captcha/email?email="+email,
method:'GET',
success:function (result){
code = result['code']
if (code == 200)
{
var countdown = 5;
var timer = setInterval(function ()
{
$this.text(countdown);
countdown-=1;
if (countdown<=0){
clearInterval(timer);//运行了五秒,为了关闭计时就得clearInterval(timer)
$this.text("获取验证码");
bindEmailCaptcha();
}
},1000)
}
else{
alert("youxiangfasonghshibai")
}
//result 是后端auth.py邮箱获取邮箱验证码的返回值
},
fail:function (error){
console.log(error)
}
});
});
}
$(function ()//整个网页加载完成后才执行这个函数
{
bindEmailCaptcha();
});
其中ajax 请求参数的url地址传到服务器后,服务器会直接运行该网页(真正完成了数据往数据库存放)
@bp.route("/captcha/email")
def get_email_captcha():#发送验证码 随机的四位
####生成验证码
# 我们有两种传参方式
# /captcha/email/<email> 根据路径传参 用<>来传递参数
#/captcha/email?email=2036801580@qq.com
email = request.args.get("email")
source = 4*string.digits#'0123456789012345678901234567890123456789'
captcha = random.sample(source,4)#随机四位验证码长度
captcha = ''.join(captcha)#把列表变成字符串 就是列表袁术拼接
###发送验证码
message = Message(subject='验证码查收!',recipients = [email],body = f"您的验证码为:{captcha}")
mail.send(message)
# 把邮箱和验证码传入到数据库中
#memcached/redis 缓存 验证码在服务器也得存储一份
#用数据库中存储验证码,偏慢一点
email_catpcha = EmailCaptchaModel(email=email,captcha=captcha)
db.session.add(email_catpcha)
db.session.commit()
#restful api 返回数据统一一个格式
# {code :200/400/500,message:"“,data:{}}
return jsonify({'code':200,"messzge":"",'data':None})
# return f"验证码为{captcha}"
在执行完上面数据存放数据库后,用户提交表单即会向服务器发送数据即POST则会执行把用户账号密码存入数据库总,即注册页面到此完成!!!!
题外话
对于.forms什么含义,下面有newbing给出的答案
在 Python 中,点号 (.) 用于表示相对导入。在这种情况下,from .forms import Registerform 表示从当前模块所在的包中导入 forms 模块中的 Registerform 类。
相对导入允许您根据当前模块的位置来导入其他模块,而不是根据系统路径。这样,您可以更轻松地移动和重构代码,而不必担心导入语句的更改。
例如,假设您有一个名为 myapp 的包,其中包含两个模块:main.py 和 forms.py。在 main.py 中,您可以使用相对导入来导入 forms.py 中定义的 Registerform 类,如下所示:
Python
此代码由 AI 生成。仔细查看和使用。有关详细信息,请访问我们的常见问题解答。
from .forms import Registerform
这里,点号 (.) 表示当前模块所在的包,即 myapp 包。因此,上面的导入语句等效于以下绝对导入语句:
Python
此代码由 AI 生成。仔细查看和使用。有关详细信息,请访问我们的常见问题解答。
from myapp.forms import Registerform
相对导入可以使用多个点号来表示不同级别的相对位置。例如,两个点号 (…) 表示当前模块所在包的父包,三个点号 (…) 表示当前模块所在包的祖父包,依此类推。需要注意的是,相对导入只能用于包内部,不能用于顶层模块。