23 - form表单验证 - 图形验证码

绘制验证码

        (1). 安装库文件

pip install pillow==8.3.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/

        (2). 封装绘制验证码函数

import os
import random
from PIL import Image, ImageFont, ImageDraw, ImageFilter

def get_random_color():
    # 获取随机颜色
    return (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))


def generate_image(length):
    s = 'hjksdbasbDAEDdihwdjbb12345678nnvzx90ADASDDASDDAD'
    size = (130, 50)
    # 创建一个画布
    im = Image.new("RGB", size, color=get_random_color())

    # 创建字体: 写绝对路径
    font = ImageFont.truetype(os.path.dirname(__file__)+'\\font\\pop字体.ttf', size=35)

    # 创建ImageDraw对象
    draw = ImageDraw.Draw(im)
    # 绘制验证码
    code = ""
    for i in range(length):
        c = random.choice(s)  # 随机取一个
        code += c
        # text((x,y坐标),内容,颜色,字体)
        draw.text((5 + random.randint(4, 7) + 25 * i, 1),
                  text=c,
                  fill=get_random_color(),
                  font=font)

    # 绘制干扰线
    for i in range(6):
        x1 = random.randint(0, 130)
        y1 = random.randint(0, 50 / 2)

        x2 = random.randint(0, 130)
        y2 = random.randint(50 / 2, 50)
        draw.line(((x1, y1), (x2, y2)), fill=get_random_color())

    # 滤镜
    im = im.filter(ImageFilter.EDGE_ENHANCE)

    # 生成图片
    # im.show()
    return im, code


if __name__ == '__main__':
    # (<PIL.Image.Image image mode=RGB size=130x50 at 0x17CB8F8>, '60wi')
    print(generate_image(4))

        (3). form.py 增加表单验证

from flask import session
from flask_wtf import FlaskForm


from wtforms import StringField, ValidationError


# 1. form表单增加验证码输入框和校验验证码
class UserForm(FlaskForm):
    # 验证码输入框
    recaptcha = StringField(label="验证码")

    def validate_recaptcha(self, data):
        # 用户输入的验证码
        input_code = data.data
        print(data)
        # 将后台生成的验证码保存在session中
        code = session.get('valid')
        if input_code.lower() != code.lower():
            raise ValidationError("验证码错误")

        (4). 视图函数调用 form对象传递给前端, 并实现点击刷新验证码接口

from io import BytesIO

from flask import Blueprint, session, make_response, render_template

from util.form import UserForm
from util.pillow import generate_image

user_bp = Blueprint('user', __name__)


@user_bp.route('/',methods=["GET","POST"])
def index():
    uform = UserForm()
    if uform.validate_on_submit(): # 主要通过validate_on_submit 进行校验
        print(uform.recaptcha)
        return "请求成功"
    return render_template("user/index.html",uform=uform)



@user_bp.route('/image')
def get_image():
    im, code = generate_image(4)

    # 将image对象转成二进制
    buffer = BytesIO()

    # 保存buffer.jpeg
    im.save(buffer, 'JPEG')
    buf_bytes = buffer.getvalue()  # 读取
    # 保存验证码到session中(推荐redis中)
    session['valid'] = code
    response = make_response(buf_bytes)
    response.headers["Content-Type"] = "image/jpg"
    return response

        (5). 前端通过form对象生成页面, 点击更新img标签路径,实现刷新验证码功能

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form action="{{ url_for('user.index') }}" method="post" enctype="multipart/form-data" novalidate>
    {#  csrf验证 #}
    {{ uform.csrf_token }}

    <p>
        {{ uform.recaptcha.label }}:{{ uform.recaptcha }}
        <img id="img" src="{{ url_for('user.get_image') }}" alt="">
    </p>
    <p>{% if uform.recaptcha.errors %}{{ uform.recaptcha.errors.0 }}{% endif %}</p>

    <p><input type="submit" value="提交"></p>
</form>

</body>
{# 2. 编写js,点击刷新验证码#}
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>
    $("#img").click(function () {
        console.log(".......")
        $(this).attr('src', "{{ url_for('user.get_image') }}?ran=" + Math.random());
    })
</script>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值