• Django 系列博客(十四)


    Django 系列博客(十四)

    前言

    本篇博客介绍在 html 中使用 ajax 与后台进行数据交互。

    什么是 ajax

    ajax(Asynchronous Javascript And XML)翻译成中文就是‘’异步 JavaScript 和 XML‘’。即使用 JavaScript 语言与服务器进行异步交互,传输的数据为 XML(现在更多地使用 json)。

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,也能发出第二个请求。

    ajax 除了异步的特点外,还有一个就是:浏览器页面局部刷新。在页面没有进行刷新的情况下进行数据交互。

    优点:

    • ajax 使用JavaScript 技术向服务器发送异步请求;
    • ajax 无需刷新整个页面。

    基于 jQuery 的 ajax 实现

    前端代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <script src="/static/jquery-3.3.1.js"></script>
    
        <title>regist</title>
    {#    <link rel="stylesheet" href="/static/jquery-3.3.1.js">#}
    </head>
    <body>
    <p>用户:<input type="text" id="name"></p>
    <p>密码:<input type="password" id="pwd"></p>
    <p>确认密码:<input type="password" id="tpwd"></p>
    <input type="button" id="submit" value="提交"><span id="error"></span>
    </body>
    
    <script>
    
        $('#submit').click(function () {
            console.log($('#submit'));
            {#$.ajax({#}
            {#    url:'/regist/',#}
            {#    type:'post',#}
            {#    data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd")},#}
            {#    success:function (data) {#}
            {#        console.log(data)#}
            {#    }#}
            $.ajax({
                url:'/regist/',
                type:'post',
                data:{name:$("#name").val(), pwd:$("#pwd").val(), tpwd:$("#tpwd").val()},
                success:function (data) {
                    console.log(data)
                }
            })
    
        })
    </script>
    </html>
    

    后端代码

    from django.http import JsonResponse
    from django.shortcuts import render, redirect
    from app01.models import *
    
    # Create your views here.
    
    
    def wrapper(func):
        def inner(*args, **kwargs):
            if args[0].method == 'GET':
                return func(*args, **kwargs)
            elif kwargs['contentType'] == 'application/json':
                import json
                args[0].POST = json.loads(args[0].body)
                return func(*args, **kwargs)
            else:
                return func(*args, **kwargs)
        return inner
    
    import json
    # json.loads()
    
    
    def regist(request):
        dic = {'status': 200, 'msg': None}
        print(request.body)
        if request.method == 'GET':
            return render(request, 'regist.html')
        else:
            print('/////')
            print(request.POST, 'dddd')
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
            tpwd = request.POST.get('tpwd')
    
            user = UserInfo.objects.filter(name=name).first()
            if user:
                dic['status'] = 100
                dic['msg'] = '用户已存在'
                return JsonResponse(dic)
            else:
                if name and pwd and tpwd:
                    if pwd == tpwd:
                        UserInfo.objects.create(name=name, pwd=pwd)
                        dic['msg'] = '注册成功'
                        return JsonResponse(dic)
                    else:
                        dic['status'] = 101
                        dic['msg'] = '两次密码不一样'
                        return JsonResponse(dic)
                else:
                    dic['status'] = 101
                    dic['msg'] = '密码不正确'
                    return JsonResponse(dic)
    
    
    @wrapper
    def login(request):
        dic = {'status': 200, 'msg': None}
        if request.method == 'GET':
            return render(request, 'login.html')
        else:
            name = request.POST.get('name')
            pwd = request.POST.get('pwd')
    
            user = UserInfo.objects.filter(name=name).first()
            if not user:
                dic['status'] = 100
                dic['msg'] = '用户不存在,请注册'
                return JsonResponse(dic)
            else:
                if pwd == user.pwd:
                    dic['msg'] = '登陆成功'
                    return JsonResponse(dic)
                else:
                    dic['status'] = 101
                    dic['msg'] = '密码错误'
                    return JsonResponse(dic)
    

    js代码

    $("#submit3").click(function () {
                $.ajax({
                    url: '/auth/',
                    type: 'post',
                    data: {
                        'user': $("#id_name").val(),
                        'password': $('#id_password').val()
                    },
    
                    success: function (data) {
                        {#console.log(data)#}
                        var data=JSON.parse(data)
                        if (data.user){
                            location.href='https://www.baidu.com'
                        }else {
                            $(".error").html(data.message).css({'color':'red','margin-left':'20px'})
                        }
                    }
    
    
                })
            }
        )
    

    文件上传

    请求头

    1. application/x-www-form-urlencoded

    这是最常见的 POST 提交数据的方式了。浏览器的原生

    表单,如果不设置 enctype 属性,那么最终会以 application/x-www-form-urlencoded方式提交数据。类似于下面:

    POST http://www.example.com HTTP/1.1
    Content-Type: application/x-www-form-urlencoded;charset=utf-8
    
    请求体
    
    1. multipart/form-data

    当我们使用表单上传文件时,必须让表单的 enctype 等于multipart/form-data。

    POST http://www.example.com HTTP/1.1
    Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
    
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
    Content-Disposition: form-data; name="user"
    
    yuan
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA
    Content-Disposition: form-data; name="file"; filename="chrome.png"
    Content-Type: image/png
    
    PNG ... content of chrome.png ...
    ------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
    

    这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以--boundary 开始,紧接着是内容描述信息,然后回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以--boundary--表示结束。

    这种方式一般用于上传文件,各大服务端语言也有很好的支持。

    这两种POST 提交的方式,都是浏览器原生支持的,而且先阶段标准中原生表单也只支持这两种方式(通过元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded)。随着越来越多的web站点尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

    1. application/json

    application/json是另外一种请求头,不过更多的是作为响应头,因为 json 格式的数据时通用数据格式。不过目前也用来作为请求头,用来告诉服务器端主体是序列化后的 json 字符串。由于 json 规范的流行,除了低版本的 IE 之外的各大浏览器都原生支持 json.stringfy,服务器端语言也都有处理 json数据的函数,使用 json 不会遇到什么麻烦。

    json 格式支持比键值对复杂的多的结构化数据,这点对数据传输很有用。

    基于form表单上传文件

    前端代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <form action="" method="post" enctype="multipart/form-data">
        <p>用户名:<input type="text" name="name"></p>
        <input type="file" name="myfile">
    {#    <input type="file" name="myfile2">#}
        <input type="submit" value="提交">
    
    </form>
    
    </body>
    </html>
    

    后端代码

    class UploadFile(View):
    
        def get(self, request):
            return render(request, 'upload_file.html')
    
        def post(self, request):
            file = request.FILES.get('myfile')
            # print(file['file'])
            from django.core.files.uploadedfile import InMemoryUploadedFile
            print(time.time())
            filename = str(time.time()).split('.')[0] + file.name
            with open(filename, 'wb') as f:
                for line in file:
                    f.write(line)
            return HttpResponse('上传成功')
    

    基于ajax 的文件上传

    前端代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>uploadfile</title>
        <script src="/static/jquery-3.3.1.js"></script>
    </head>
    <body>
    <p>用户名:<input type="text" id="name"></p>
    <p>选择文件:<input type="file" id="my_file"></p>
    <button id="btn">上传</button><span id="msg"></span>
    </body>
    
    <script>
        $('#btn').click(function () {
            var myfile = $('#my_file')[0].files[0];
            var formdata = new FormData();
            formdata.append('name', $('#name').val());
            formdata.append('myfile', myfile);
            $.ajax({
                url:'/uploadfile/',
                type:'post',
                processData:false, // 告诉 jQuery 不要处理发送的数据
                contentType:false, // 告诉 jQuery 不要设置 Content-Type 请求头
                data:formdata,
                success:function (data) {
                    console.log(data);
                    $('#msg').text(data)
                }
            })
        })
    
    </script>
    </html>
    

    后端代码

    MEDIA_PATH = '/Users/jingxing/Django/homework/paging/media'
    
    def uploadfile(request):
        if request.method == 'GET':
            return render(request, 'uploadfile.html')
        else:
    
            myfile = request.FILES.get('myfile')
            print(myfile)
            filepath = os.path.join(MEDIA_PATH, myfile.name[32:-3]+'jpg')
            with open(filepath, 'wb') as f:
                for line in myfile:
                    f.write(line)
            FileInfo.objects.create(name=request.POST.get('name'), filepath=filepath)
            return HttpResponse('上传成功')
    

    ajax 提交 json 格式数据

    前端代码

    $('#submit1').click(function () {
            postdata={name1:$("#name").val(),pwd2:$("#pwd").val()}
            $.ajax({
                url:'/loginjson/',
                type:'post',
                // 指定提交的编码格式是json格式,
                contentType:'application/json',
                data:JSON.stringify(postdata),
                // data:postdata,
                // data:'123',
                success:function (data) {
                    console.log(data)
    
                }
            })
        })
    

    后端代码

    def loginjson(request):
        dic={'status':100,'msg':None}
        if request.method=='POST':
            print(request.POST)
            print(request.GET)
            print(request.body)
            xx=request.body.decode('utf-8')
            # re是个字典{"name1":"lqz","pwd2":"123"}
            re=json.loads(xx)
            request.POST=11
    
    
            print(request.POST)
            #
            #
            # name=re.get('name1')
            # pwd=re.get('pwd2')
            # print(name)
            # print(pwd)
            return HttpResponse('ok')
    

    后端返回 json 数据

    前端代码

    $('#submit').click(function () {
            $.ajax({
                url:'/login/',
                type:'post',
                data:{name1:$("#name").val(),pwd2:$("#pwd").val()},
                success:function (data) {
                    //后台用JsonResponse返回数据
                    //data 就会被转成字典
                    console.log(data)
                    console.log(typeof data)
                    //JSON.parse(data) 把字符串类型转成字典
                    data=JSON.parse(data)
                    {#JSON.stringify()#}
                    console.log(typeof dat1)
                    if(data.status == 100){
                        //成功,跳转到指定页面
                        //location.href=地址,前端就会跳转到指定的url
                        alert(data.msg)
                        //$("#error").text(data.msg+'正在跳转')
                        //location.href=data.url
                    }else{
                        $("#error").text(data.msg)
                    }
    
    
                }
            })
        })
    

    后端代码

    def login(request):
        dic={'status':100,'msg':None}
        if request.method == 'GET':
            return render(request, 'login.html')
        # if request.is_ajax():
        if request.method=='POST':
            name=request.POST.get('name1')
            pwd=request.POST.get('pwd2')
            if name=='lqz' and pwd=='123':
                dic['msg'] = '登陆成功'
                # 想让前端跳转
                # dic['url']='http://www.baidu.com'
                dic['url']='/test/'
            else:
                # 返回json格式字符串
                dic['status']=101
                dic['msg']='用户名或密码错误'
            # return JsonResponse(dic)
            return HttpResponse(json.dumps(dic))
    

    Django内置的序列化数据方法

    from django.core import serializers
    
    def test(request):
        book_list = Book.objects.all()
        ret = serializers.serialize('json', book_list)
        return HttpResponse(ret)
    
  • 相关阅读:
    实现 RSA 算法之改进和优化(第三章)(老物)
    实现 RSA 算法之 C 语言实现(第二章)(老物)
    实现 RSA 算法之基础公式证明(第一章)(老物)
    mapreducer计算原理
    Job的运行过程
    HDFS之JAVAAPI
    HDFS文件操作
    HdfS体系结构
    hdfs(分布式文件系统)优缺点
    hadoop的单机配置
  • 原文地址:https://www.cnblogs.com/zuanzuan/p/10294294.html
Copyright © 2020-2023  润新知