基于form表单和ajax的登录示例

Posted zh_小猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于form表单和ajax的登录示例相关的知识,希望对你有一定的参考价值。

  1 urls.py

from blog import views

urlpatterns = [
    url(r\'^login/\', views.login),
    url(r\'^index/\', views.index),
    #获取验证码图片的url
    url(r\'^get_valid_img.png/\', views.get_valid_img),
# 极验滑动验证码 获取验证码的url url(r\'^pc-geetest/register\', views.get_geetest), ]

2 views.py

from django.shortcuts import render, HttpResponse
from django.http import JsonResponse
from django.contrib import auth
from geetest import GeetestLib
# Create your views here.

# VALID_CODE = ""


# 自己生成验证码的登录
def login(request):

    # if request.is_ajax():  # 如果是AJAX请求
    if request.method == "POST":
        # 初始化一个给AJAX返回的数据(只要是用ajax做前后端校验,后端视图函数就应该先定义一个小字典)
        ret = {"status": 0, "msg": ""}
        # 从提交过来的数据中 取到用户名和密码
        username = request.POST.get("username")
        pwd = request.POST.get("password")
        valid_code = request.POST.get("valid_code")  # 获取用户填写的验证码
        print(valid_code)
        print("用户输入的验证码".center(120, "="))
        #先校验验证码(可以区分大小写也可以不区分 不区分:统一转大写或者小写进行比对即可)
        if valid_code and valid_code.upper() == request.session.get("valid_code", "").upper():
            # 验证码正确
            # 利用auth模块做用户名和密码的校验
            user = auth.authenticate(username=username, password=pwd)
            if user:
                # 用户名密码正确
                # 登录成功记录当前用户状态
                auth.login(request, user)
                ret["msg"] = "/index/"
            else:
                # 用户名密码错误
                ret["status"] = 1
                ret["msg"] = "用户名或密码错误!"
        else:
            ret["status"] = 1
            ret["msg"] = "验证码错误"

        return JsonResponse(ret)
    return render(request, "login.html")


# 使用极验滑动验证码的登录
# def login(request):
#     # if request.is_ajax():  # 如果是AJAX请求
#     if request.method == "POST":
#         # 初始化一个给AJAX返回的数据
#         ret = {"status": 0, "msg": ""}
#         # 从提交过来的数据中 取到用户名和密码
#         username = request.POST.get("username")
#         pwd = request.POST.get("password")
#         # 获取极验 滑动验证码相关的参数
#         gt = GeetestLib(pc_geetest_id, pc_geetest_key)
#         challenge = request.POST.get(gt.FN_CHALLENGE, \'\')
#         validate = request.POST.get(gt.FN_VALIDATE, \'\')
#         seccode = request.POST.get(gt.FN_SECCODE, \'\')
#         status = request.session[gt.GT_STATUS_SESSION_KEY]
#         user_id = request.session["user_id"]
#
#         if status:
#             result = gt.success_validate(challenge, validate, seccode, user_id)
#         else:
#             result = gt.failback_validate(challenge, validate, seccode)
#         if result:
#             # 验证码正确
#             # 利用auth模块做用户名和密码的校验
#             user = auth.authenticate(username=username, password=pwd)
#             if user:
#                 # 用户名密码正确
#                 # 给用户做登录
#                 auth.login(request, user)
#                 ret["msg"] = "/index/"
#             else:
#                 # 用户名密码错误
#                 ret["status"] = 1
#                 ret["msg"] = "用户名或密码错误!"
#         else:
#             ret["status"] = 1
#             ret["msg"] = "验证码错误"
#
#         return JsonResponse(ret)
#     return render(request, "login2.html")


def index(request):
    return render(request, "index.html")


# 获取验证码图片的视图
def get_valid_img(request):

    from PIL import Image, ImageDraw, ImageFont, ImageFilter
    #Image用来生成图片 ImageDraw在图片上写’字\' ImageFont用来控制字体样式,ImageFilter让图片模糊化
    import random

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

    # 生成一个图片对象
    img_obj = Image.new(
        \'RGB\',
        (220, 35),
        get_random_color()
    )
    # 在生成的图片上写字符
    # 生成一个图片画笔对象
    draw_obj = ImageDraw.Draw(img_obj)  #你的画笔就可以在该图片上为所欲为
    # 加载字体文件, 得到一个字体对象
    font_obj = ImageFont.truetype("static/font/kumo.ttf", 28)
    # 开始生成随机字符串并且写到图片上
    tmp_list = [] #定义一个变量存储最终验证码
    for i in range(5):
        u = chr(random.randint(65, 90))  # 生成大写字母
        l = chr(random.randint(97, 122))  # 生成小写字母
        n = str(random.randint(0, 9))  # 生成数字,注意要转换成字符串类型

        tmp = random.choice([u, l, n])
        tmp_list.append(tmp)
        draw_obj.text((20+40*i, 0), tmp, fill=get_random_color(), font=font_obj)

    print("".join(tmp_list))
    print("生成的验证码".center(120, "="))
    # 不能保存到全局变量
    # global VALID_CODE
    # VALID_CODE = "".join(tmp_list)

    # 将valid_code保存到session表中
    request.session["valid_code"] = "".join(tmp_list)
    # 加干扰线
    # width = 220  # 图片宽度(防止越界)
    # height = 35
    # for i in range(5):
    #     x1 = random.randint(0, width)
    #     x2 = random.randint(0, width)
    #     y1 = random.randint(0, height)
    #     y2 = random.randint(0, height)
    #     draw_obj.line((x1, y1, x2, y2), fill=get_random_color())
    #
    # # 加干扰点
    # for i in range(40):
    #     draw_obj.point((random.randint(0, width), random.randint(0, height)), fill=get_random_color())
    #     x = random.randint(0, width)
    #     y = random.randint(0, height)
    #     draw_obj.arc((x, y, x+4, y+4), 0, 90, fill=get_random_color())

    # # 将生成的图片保存在磁盘上
    # with open("s10.png", "wb") as f:
    #     img_obj.save(f, "png")
    # # 把刚才生成的图片返回给页面
    # with open("s10.png", "rb") as f:
    #     data = f.read()

    # 不需要在硬盘上保存文件,直接在内存中加载就可以
    from io import BytesIO
    #能够帮你保存数据 并且在取的时候会以二进制的形式返回给你

    #生成一个BytesIO对象
    io_obj = BytesIO()     #将生成的对象看成文件句柄
    # 将生成的图片数据保存在io对象(内存管理器)中,需要指定图片格式
    # img_obj = img_obj.filter(ImageFilter.BLUR)  #让图片变的模糊
    img_obj.save(io_obj, "png")
    # 从io对象里面取上一步保存的数据
    data = io_obj.getvalue()
    return HttpResponse(data)


# 请在官网申请ID使用,示例ID不可使用
pc_geetest_id = "b46d1900d0a894591916ea94ea91bd2c"
pc_geetest_key = "36fc3fe98530eea08dfc6ce76e3d24c4"


# 处理极验 获取验证码的视图
def get_geetest(request):
    user_id = \'test\'
    gt = GeetestLib(pc_geetest_id, pc_geetest_key)
    status = gt.pre_process(user_id)
    request.session[gt.GT_STATUS_SESSION_KEY] = status
    request.session["user_id"] = user_id
    response_str = gt.get_response_str()
    return HttpResponse(response_str)

3 login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎登录</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
</head>
<body>

<div class="container">
    <div class="row">
        <form class="form-horizontal col-md-6 col-md-offset-3 login-form">
            {% csrf_token %}
            <div class="form-group">
                <label for="username" class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="username" name="username" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">验证码</label>
                <div class="col-sm-10">
                    <input type="text" name="valid_code" id="valid_code">
                    <img id="valid-img" class="valid-img" src="/get_valid_img.png?" alt="">
                </div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default" id="login-button">登录</button>
                    <span class="login-error"></span>
                </div>
            </div>
        </form>
    </div>
</div>

<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
    $("#login-button").click(function () {
        // 1. 取到用户填写的用户名和密码 -> 取input框的值
        var username = $("#username").val();
        var password = $("#password").val();
        var valid_code = $("#valid_code").val();
        // 2. 用AJAX发送到服务端
        $.ajax({
            url: "/login/",
            type: "post",
            data: {
                "username": username,
                "password": password,
                "valid_code": valid_code,
                "csrfmiddlewaretoken": $("[name=\'csrfmiddlewaretoken\']").val()
                //"csrfmiddlewaretoken": \'{{ csrf_token }}\'

            },
            success: function (data) {
                console.log(data);
                if (data.status) {
                    // 有错误,在页面上提示
                    $(".login-error").text(data.msg);
                } else {
                    // 登陆成功
                    location.href = data.msg;
                }
            }
        })
    });

    // 当input框获取焦点时将之前的错误清空
    $("#username,#password").focus(function () {
        // 将之前的错误清空
        $(".login-error").text("");
    });

    // 点击验证码图片 刷新验证码
    $("#valid-img").click(function () {
        $(this)[0].src += "?";
    })
</script>
</body>
</html>

4 login2.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>欢迎登录</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
    <link rel="stylesheet" href="/static/mystyle.css">
</head>
<body>

<div class="container">
    <div class="row">
        <form class="form-horizontal col-md-6 col-md-offset-3 login-form">
            {% csrf_token %}
            <div class="form-group">
                <label for="username" class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-10">
                    <input type="text" class="form-control" id="username" name="username" placeholder="用户名">
                </div>
            </div>
            <div class="form-group">
                <label for="password" class="col-sm-2 control-label">密码</label>
                <div class="col-sm-10">
                    <input type="password" class="form-control" id="password" name="password" placeholder="密码">
                </div>
            </div>
            <div class="form-group">
                <!-- 放置极验的滑动验证码 -->
                <div id="popup-captcha"></div>
            </div>
            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <button type="button" class="btn btn-default" id="login-button">登录</button>
                    <span class="login-error"></span>
                </div>
            </div>
        </form>
    </div>
</div>

<script src="/static/jquery-3.3.1.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<!-- 引入封装了failback的接口--initGeetest -->
<script src="http://static.geetest.com/static/tools/gt.js"></script>
<script>

    // 

以上是关于基于form表单和ajax的登录示例的主要内容,如果未能解决你的问题,请参考以下文章

django 基于form表单上传文件和基于ajax上传文件

Ajax提交form表单

Django框架form表单配合ajax注册

Ajax OR Form !

form表单利用iframe高仿ajax

django登录表单和表单验证在引导模式中使用ajax