Django Ajax知识

Ajax

AJAXAsynchronous Javascript And XML)翻译成中文就是异步JavascriptXML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。

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

AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

 

优点:

  • AJAX使用Javascript技术向服务器发送异步请求
  • AJAX无须刷新整个页面

 基于Ajax的登录验证

用户在表单输入用户名与密码,通过Ajax提交给服务器,服务器验证后返回响应信息,客户端通过响应信息确定是否登录成功,成功,则跳转到首页,否则,在页面上显示相应的错误信息。

HTML文件 

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Ajax登录验证</title>
    <script src="/static/jquery-3.3.1.js"></script>
</head>
<body>

<from>
    用户名 <input type="text" id="user">
    密码 <input type="password" id="pwd">
    <input type="button" class="login-btn" value="提交">
    <span class="error"></span>
</from>


</body>
<script>
    $('.login-btn').click(function () {
        $.ajax({
            url: '/auth_login/',
            type: 'post',
            data: {
                'user': $('#user').val(),
                'pwd': $('#pwd').val(),
            },
            success: function (data) {
                console.log(data);
                    console.log(typeof data);
                {# 把接收的字符转换成js能别的json数据#}
                var data = JSON.parse(data);
                console.log(data);
                console.log(typeof data);
                console.log(data.user)
                if (data.user) {
                    location.href = 'https://www.baidu.com'
                } else {
                    $('.error').html(data.msg).css({'color':'red','margin-left':'10px'})
                }

            }
        })
    })


</script>


</html>

后端代码

def auth_login(request):

    print(request.POST)
    username = request.POST.get('user')
    pwd = request.POST.get('pwd')
    auth = user.objects.filter(name=username,pwd=pwd).first()
    ret = {'user
':None,'msg':None} if auth: ret['user'] = auth.name else: ret['msg'] ='username or password wrong!' return HttpResponse(json.dumps(ret))

基于from表单的文件上传

 

请求头ContentType

 ContentType指的是请求体的编码类型,常见的类型共有3种:

1 application/x-www-form-urlencoded

 这应该是最常见的 POST 提交数据的方式了。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。:

<from>
    用户名 <input type="text" id="user">
    密码 <input type="password" id="pwd">
    <input type="button" class="login-btn" value="提交">
    <span class="error"></span>
</from>

上面的from表单中,没有设置enctype属性.通过F12来查看请求信息的时候,我们可以看到:Content-Type:application/x-www-form-urlencoded; charset=UTF-8

2 multipart/form-data

 这是一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。直接来看一个请求示例:

 

<form action="" method="post" enctype="multipart/form-data" >
    文件名 <input type="file" name="header-ico" id="file">
    <input type="submit" class="sub-btn" >

</form>

请求信息:Content-Type: multipart/form-data; boundary=----WebKitFormBoundary0LhrB6nJGlWvdFz9

3 application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

文件上传 完整的例子:

HTML
file_input.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>基于form表单的文件上传</title>
    <script src="/static/jquery-3.3.1.js"></script>
</head>
<body>
<form action="" method="post" enctype="multipart/form-data" >
    文件名 <input type="file" name="header-ico" id="file">
    <input type="submit" class="sub-btn" >

</form>
</body>

</html>

 Django代码

 views.py

def file_input(request):
    if request.method=='POST':
        print(request.POST)
        print('文件信息:',request.FILES)
        file_obj = request.FILES.get('header-ico')
        with open(file_obj.name,'wb')as f:
            for line in file_obj:
                f.write(line)
        return HttpResponse('ok')

    return  render(request,'file_input.html')

基于Ajax的文件上传

 jQuery获取文件的方式:

'''
$('文件id或class')[0].files[0]:获取的是一个文件对象.它的属性有:
name:文件完整的名称,包含后缀名
lastModified:最后修改时间,格式为时间戳格式
lastModifiedDate: 最后修改的时间,格式为日期型
webkitRelativePath:文件路径
size:文件大小,格式为字节,转换为KB需要除以1024
type:文件类型

'''
 html文件

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>基于form表单的文件上传</title>
    <script src="/static/jquery-3.3.1.js"></script>
</head>
<body>

<hr>

<h3>基于ajax的文件上传</h3>

<form action="" method="post">
    用户名 <input type="text" id="user">
    文件名 <input type="file"  id="ajax_file">
    <input type="button" class="btn" value="上传">
    <input type="button" class="sub-btn" value="测试" onclick="javascript:check()">

</form>




</body>
<script>

    $('.btn').click(function () {
           var files_obj = $('#ajax_file')[0].files[0];
        console.log(files_obj.size);

        var file_size = files_obj.size;
        if (file_size/1024>512){
            alert('上传的文件大于500KB,请重新上传!');
            console.log('上传失败!');
            return false
        }else {
            console.log('上传成功!');
        }
         {#以下是固定格式,如果是使用ajax来上传文件,必须要按照以下格式来写,新建一个fromdata对象,#}
{#        并在ajax中添加2个参数:contentType:false,processData:false.processData:是否对数据进行预处理,contentType:表示预处理时使用的编码格式#}
        var fromdata = new FormData();
        fromdata.append('user',$('#user').val());
        fromdata.append('header',$('#ajax_file')[0].files[0]); {# 这里的header-ico是views里,取文件对象时用到的 #}

        $.ajax({
            url:'',
            type:'post',
            contentType:false,
            processData:false,
            data:fromdata,
            success:function (data) {
                console.log('数据',data)
            }
        })



    });
    {#检测文件大小#}
    function check() {
         var files_obj = $('#ajax_file')[0].files[0];
        console.log(files_obj.size);
        for (key in files_obj) {
            console.log(key,files_obj[key]);
        }
        var file_size = files_obj.size;
        size_kb = Math.round(file_size/1024);
        {#alert(file_size);#}
        {#alert('文件大小:'+size_kb+"kb");#}
        if (size_kb>512){
            alert('上传的文件大于500KB,请重新上传!');
            $('#ajax_file').val('');
            console.log('文件太大!');
            return false
        }else {
            console.log('文件大小符合!');
        }
    }
    {#当前文件框发生变化时,调用check函数检测文件大小#}
    $('#ajax_file').change(function () {
        {#alert('文件筐已经发生变化')#}
        check()
    })


</script>
</html>
 views.py

 

def file_input(request):
    if request.method=='POST':
        # print('文件报头:', request.body)
        print(request.POST)

        # print('文件报头:', request.body)
        # 这里遇到一个坑,一直把request.body放到了request.POST后面.导致文件无法上传,且报错django.http.request.RawPostDataException: You cannot access body after reading from request's data stream
        # 猜想应该是读取信息的时候,先读取出body,才读取Post,顺序错了。就是说POST数据在body中,不能比body先读取
        print('文件信息:',request.FILES)
        file_obj = request.FILES.get('header')
        print(file_obj)
        with open(file_obj.name,'wb')as f:
            for line in file_obj:
                f.write(line)
        return HttpResponse('ok')

    return  render(request,'file_input.html')

 

 

 

 

 

 

 

原文地址:https://www.cnblogs.com/lovepy3/p/10925090.html