• Title


    Ajax简介

    什么是Ajax

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

    • 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
    • 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
      AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)

    ## Ajax应用场景 登录注册时的校验,以百度为例 ![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190326205349008-802468394.png) 当输入框失去焦点时,触发事件,浏览器发送Ajax请求,服务端进行校验,返回数据给浏览器,显示相应的错误信息 ![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190326205534125-1716891331.png) 此过程中,整个页面是没有刷新的,同时请求发出后我们还可以进行其他操作,因此是异步的,这就体现了Ajax的两大特点: `异步请求`和 `局部刷新`
    ## Ajax流程 Ajax请求的流程如下 ![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190326205950026-2135596492.png) 1. 客户端触发异步操作 2. 创建新的XMLHttpRequest对象,这是ajax的核心 3. 通过send()方法实现与server的连接 4. 服务器端接收请求,并处理 5. 返回处理的结果,这个结果可以是XML文档、也可以是josn字符串(一般情况下josn就可以处理大部分的结果、而且相对的比较好操作) 6. 在客户端去接收服务器传回来的结果,并且通过javascript进行你想要的处理

    小结

    Ajax特点

    • 异步请求
    • 局部刷新

    实例

    Ajax登录验证

    准备工作

    新建一个项目ajaxDemo,创建一个APP,命名为app1

    新建一个数据库ajaxdemo,增加User表模型
    models.py

    from django.db import models
    
    # Create your models here.
    
    
    class User(models.Model):
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=32)
    
    

    配置urls
    urls.py

    from django.contrib import admin
    from django.urls import path, re_path
    from app1 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
    ]
    

    ### 编写视图函数 views.py ```python from django.shortcuts import render, HttpResponse, redirect from app1 import models import json # Create your views here.

    def login(request):
    if request.method == "POST":
    username = request.POST.get('username')
    password = request.POST.get('password')
    response = {"status": False, "username": None, 'msg': None}
    user_obj = models.User.objects.filter(username=username, password=password).first()
    if user_obj:
    response['status'] = True
    response['username'] = username
    else:
    response['msg'] = '用户名或密码错误'
    # 注意发送之前要序列化
    return HttpResponse(json.dumps(response, ensure_ascii=False))
    else:
    return render(request, 'login.html')

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

    
    <br>
    ### 编写HTML页面
    login.html
    ```html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>用户登录</title>
        <script src="/static/plugins/js/jquery.js"></script>
    </head>
    <body>
    
    <form action="">
        {% csrf_token %}
        <p>用户名:<input type="text" name="username"></p>
        <p>密码:<input type="text" name="password"></p>
        <input type="button" class='btn' value="登录">
        <span class="error"></span>
    </form>
    
    
    <script>
        $('.btn').on('click', function () {
            $.ajax({
                url: '/login/',
                //注意这里的方式是type,不是method!!!
                type: 'post',
                data: {
                    username: $("[name='username']").val(),
                    password: $("[name='password']").val(),
                    csrfmiddlewaretoken: $("[name='csrfmiddlewaretoken']").val(),
                },
                //成功之后执行回调函数
                success:function (data) {
                //反序列化
                console.log(data);
                //console.log(typeof data);
                data = JSON.parse(data);
                if (data['status'] == true) {
                    //登录成功跳转到个人主页
                    window.location.href = '/index/';
                } else {
                    //登录失败显示错误信息
                    $('.error').html(data['msg']).css('color','red');
                }
    
            }
            })
        })
    </script>
    
    
    </body>
    </html>
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>个人主页</title>
    </head>
    <body>
    
    <h3>欢迎来到个人主页</h3>
    
    </body>
    </html>
    

    密码正确时
    ![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190326214637742-925346363.gif)
    密码错误时
    ![](https://img2018.cnblogs.com/blog/1542801/201903/1542801-20190326214647190-699313987.gif)
    ## 小结 ### Ajax语法 发送Ajax请求的语法为:`$.ajax({ })`,大括号里放Ajax请求的四要素
    ### Ajax请求四要素 - url: 发送请求的网址 - type:请求的类型,注意不是method - data: 要发送的数据,是一个javascript对象,可以带上csrfmiddlewaretoken键值对 - 响应状态(通常是success)及回调函数
    ### 需要注意的地方 - 前端页面发送Ajax请求时要带上csrfmiddlewaretoken,否则会返回403 - 视图函数里登录成功后不能直接跳转,应返回一个字典(记录状态)交给前端页面完成跳转 - 返回字典之前要序列化(json.dumps()) - 前端页面跳转使用`window.location.href = '/index/'`
    ajax还有其他参数,可以设置,如下: ```html ```

    响应错误时,会执行error中的代码。

    当 AJAX 请求正在进行时,执行complete的代码。它可以做一个请求等待的效果!


    ## ajax文件上传 首先来看form表单上传文件 ### 上传文件

    修改urls.py,增加路径file_upload

    from django.contrib import admin
    from django.urls import path, re_path
    from app1 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        path('index/', views.index),
        path('file_put', views.file_upload),
    ]
    
    

    修改views.py,增加视图函数file_upload
    def file_upload(request):
        if request.method == "POST":
            print(request.POST)
            return HttpResponse('ok')
        return render(request, 'file_upload.html')
    
    

    在templates里面增加页面file_put.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    
    <h3>form表单文件上传</h3>
    <form action="" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="text" name="user">
        <input type="file" name="img"><br/><br/>
        <input type="submit">
    </form>
    
    
    </body>
    </html>
    
    
    

    注意:enctype的类型不同,发送数据格式也会不同。

    form表单enctype默认为application/x-www-form-urlencoded。它的数据格式为key1=value1&key1=value1形式。

    它不能发送图片,那么需要指定为multipart/form-data才可以!


    选中一个文件,提交

    pycharm控制台打印的信息

    <QueryDict: {'csrfmiddlewaretoken': ['MiMUVVMla9s9TJ6CVYV4JUiQ6FJFlvU7GBs7RiMEQOfcm2jlybLSEOZBLvZVuEIP'], 'user': ['']}>
    
    

    可以看到request.POST里面并没有文件的信息,这是因为Django把文件单独封装到另一个属性里面了,这就是request.FILS


    修改视图函数
    def file_upload(request):
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)
            return HttpResponse('ok')
        return render(request, 'file_upload.html')
    
    

    查看pycharm控制台打印的信息 ```python ]}>
    这次得到了img信息,它的类型为MultiValueDict。描述了图片的文件名以及图片类型jpeg
    
    <br>
    ### 存储文件
    
    以上完成了从浏览器上传的部分,但是服务器接收之后还得对文件进行处理如存放等操作
    
    修改file_upload视图函数
    
    ```python
    def file_upload(request):
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)  # 打印文件信息
    
            file_obj = request.FILES.get('img')
            print(file_obj)
            print(type(file_obj))  # 打印file_obj对象属性
            print(file_obj.name)
    
            with open(file_obj.name, 'wb') as f:
                for line in file_obj:
                    f.write(line)  # 写入文件
    
            return HttpResponse('ok')
        return render(request, 'file_upload.html')
    
    

    重新上传,查看控制台打印信息 ```python ]}> 闭嘴.gif 闭嘴.gif ```

    左侧目录下出现了一张图片

    因为没有指定路径,所以默认是项目根目录


    ### 指定路径存储

    在项目根目录下新建statics文件夹,再在statics目录下新建imgs文件夹

    修改file_upload视图函数

    def file_upload(request):
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)  # 打印文件信息
    
            file_obj = request.FILES.get('img')
            print(file_obj)
            print(type(file_obj))  # 打印file_obj对象属性
            print(file_obj.name)
    
            with open('statics/imgs/' + file_obj.name, 'wb') as f:
                for line in file_obj:
                    f.write(line)  # 写入文件
    
            return HttpResponse('ok')
        return render(request, 'file_upload.html')
    
    

    再次上传文件,就保存在了指定的目录


    再来看Ajax上传文件

    利用Ajax和FormData实现页面无刷新的文件上传效果,主要用到了jQuery的ajax()方法和XMLHttpRequest Level 2的FormData接口。

    修改视图函数file_upload

    def file_upload(request):
        # form表单上传
        # if request.method == "POST":
        #     print(request.POST)
        #     print(request.FILES)  # 打印文件信息
        # 
        #     file_obj = request.FILES.get('img')
        #     print(file_obj)
        #     print(type(file_obj))  # 打印file_obj对象属性
        #     print(file_obj.name)
        #     # 图片读取出来是二进制形式
        #     with open('statics/imgs/' + file_obj.name, 'wb') as f:
        #         for line in file_obj:
        #             f.write(line)  # 写入文件
        # 
        #     return HttpResponse('ok')
        # return render(request, 'file_upload.html')
        
        # Ajax上传文件
        if request.method == "POST":
            print(request.POST)
            print(request.FILES)  # 打印文件信息
            
            file_obj = request.FILES.get('img')  # 获取img对象
            print(file_obj, type(file_obj))
            print(file_obj.__dict__)
            print(file_obj.name)
            
            # 返回给ajax回调函数的数据
            response = {"status": False}
            with open('statics/imgs/' + file_obj.name, 'wb') as f:
                for line in file_obj:
                    # write的返回值是写入的字符长度
                    ret = f.write(line)
                    # 判断写入的文件是否为空,不为空时才把status置为True
                    if ret:
                        response["status"] = True
            return HttpResponse(json.dumps(response))  # 返回json数据
            
    

    修改file_upload.html ```html Title

    {#

    form表单文件上传

    #}
    {# 表单默认为application/x-www-form-urlencoded。它的数据格式为key1=value1&key1=value1形式。 #}
    {#
    #}
    {# {% csrf_token %}#}
    {# #}
    {#

    #}
    {# #}
    {#
    #}

    Ajax上传文件

    {% csrf_token %}
    <br>
    
    ## 小结
    ### form表单上传文件要点
    - 需在form表单设置enctype="multipart/form-data"然后用submit提交
    - 视图函数里用request.FILES.get('file')获取文件对象
    - 服务端接收到文件对象后对其逐行读取并写入新文件
    
    ### Ajax上传文件要点
    - 使用FormData对象发送文件数据(把FormData对象设为data的值)
    - FormData对象添加数据用`formdata.append(key,value)`的形式
    - 需要加上`processData: false`和`contentType: false`来告诉jQuery不处理数据,不设置内容类型
  • 相关阅读:
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
  • 原文地址:https://www.cnblogs.com/zzliu/p/10603452.html
Copyright © 2020-2023  润新知