AJAX简介

局部刷新,异步提交。

AJAX 不是新的编程语言,而是一种使用现有标准的新方法。它最大的有点就是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。

浏览器朝后端发送请求的方式:

访问方式 请求方式
浏览器地址栏输入url访问 GET请求
a标签href属性 GET请求
form表单 GET/POST请求
ajax GET/POST请求

这里的Ajax是jQuery封装之后的版本,所以在前端页面使用的时候要确保导入了jQuery。

AJAX实现局部刷新求和案例

在浏览器页面inpu框输入数字,点击提交按钮,向后端发送AJAX请求,后端计算出结果,在返回到前端页面,动态展示到第三个input框中,整个页面不刷新。

urls.py 路由
from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r\'^admin/\', admin.site.urls),
    url(r\'^calculate/\', views.calculate)
]
views.py
def calculate(request):
    if request.is_ajax():  # 判断是否是ajax请求
        # print(request.POST)
        num1 = request.POST.get(\'num1\')
        num2 = request.POST.get(\'num2\')
        # 先转成整型在相加
        sum_3 = int(num1)+int(num2)
        # 返回的是字符串直接用HttpResponse
        return HttpResponse(sum_3)
    return render(request, \'calculate.html\')
calculate.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>calculate</title>
    {% load static %}
 <link rel="stylesheet" type="text/css" href="{% static \'CSS/bootstrap.css\' %}"/>
    <script src="{% static \'JS/bootstrap.min.js\' %}"></script>
    <script src="{% static \'jQuery/jquery-3.6.0.min.js\' %}"></script>
{# 在前端页面使用ajax务必导入jQuery #}
</head>
<body>
<input type="text" id="inp1">+
<input type="text" id="inp2">=
<input type="text" id="inp3">
<button id="btn">计算</button>
<script>
    // 先给按钮绑定一个点击事件
    $(\'#btn\').click(function (){
        // 朝后端发送ajax请求
        $.ajax({
            // 1.指定朝哪个后端发送ajax请求
            url:\'\', // 不写就是朝当前地址提交
            // 2.请求方式
            type:\'post\', // 不指定默认就是get 都是小写
           // 3.数据 获取到两个input框的值 发送给视图层做逻辑处理
            data:{\'num1\':$(\'#inp1\').val(),\'num2\':$(\'#inp2\').val()},
            // 4.回调函数:当后端给你返回结果的时候会触发 args接收后端返回的结果
            success:function(args){
               // 5.通过DOM操作动态渲染到第三个input框里面
                $(\'#inp3\').val(args)
            }
        })
        }
    )
</script>
</body>
</html>

AJAX数据格式转化

ajax在实际业务中往往返回的不是字符串而是字典,那如果数据格式是字典的话,该怎样进行格式之间的转换呢?

第一种方法json

HttpResponse字典是不能直接返回的,需要将它转换成字符串格式,这时后我们就需要用到json进行序列化。

views.py
import json
def data(request):
    if request.is_ajax():
        print(request.POST)
        # 前面加状态码是比较标准的格式
        back_dic = {\'code\': 200, \'msg\': \'请求失败\', \'data\': {\'username\': \'jesse\'}}
        return HttpResponse(json.dumps(back_dic))
    return render(request, \'data.html\')

而针对后端传过来的字符串,前端是没办法对字符串化的字典进行取值操作的,所以需要在前端进行反序列化,将它变成html里面的Object类型,这样就可以用点语法将要去的值直接取出来。

data.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>calculate</title>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static \'CSS/bootstrap.css\' %}"/>
    <script src="{% static \'JS/bootstrap.min.js\' %}"></script>
    <script src="{% static \'jQuery/jquery-3.6.0.min.js\' %}"></script>
    {# 在前端页面使用ajax无比导入jQuery #}
</head>
<body>
<input type="text" id="inp1">
<button id="btn">获取</button>
<input type="text" id="inp2">
<script>
    $(\'#btn\').click(function () {
        $.ajax({
            url: \'\',
            type: \'post\',
            data: {\'d1\': $(\'#inp1\').val()},
            success:function (args){
                // 反序列化 让后端发送过来的字符串变成js里面的对象
                args = JSON.parse(args)
                console.log(typeof args)  // 返回的是object格式
                // 可以针对状态码做一个判断
                if (args.code == 200){
                    $(\'#inp2\').val(args.data.username)  // js里面的object取值就可以用点语法
                }else{
                   alert(args.msg)
                }
            }
        })
    })
</script>
</body>
</html>

第二种方式JsonResponse

使用JsonResonse进行序列化,这样在html页面就不需要,进行反序列化了。

views.py
from django.http import JsonResponse
# 需要导一下模块


def data(request):
    if request.is_ajax():
        print(request.POST)
        # 前面加状态码是比较标准的格式
        back_dic = {\'code\': 200, \'msg\': \'请求失败\', \'data\': {\'username\': \'jesse\'}}
        return JsonResponse(back_dic)
    return render(request, \'data.html\')
data.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>calculate</title>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static \'CSS/bootstrap.css\' %}"/>
    <script src="{% static \'JS/bootstrap.min.js\' %}"></script>
    <script src="{% static \'jQuery/jquery-3.6.0.min.js\' %}"></script>
    {# 在前端页面使用ajax无比导入jQuery #}
</head>
<body>
<input type="text" id="inp1">
<button id="btn">获取</button>
<input type="text" id="inp2">
<script>
    $(\'#btn\').click(function () {
        $.ajax({
            url: \'\',
            type: \'post\',
            data: {\'d1\': $(\'#inp1\').val()},
            success:function (args){
                console.log(typeof args)  // 返回的是object格式
                // 可以针对状态码做一个判断
                if (args.code == 200){
                    $(\'#inp2\').val(args.data.username)  // js里面的object取值就可以用点语法
                }else{
                   alert(args.msg)
                }
            }
        })
    })
</script>
</body>
</html

第三种方法前端指定json数据格式

$.ajax({
            url: \'\',
            type: \'post\',
            data: {\'d1\': $(\'#inp1\').val()},
            dataType:\'json\',
            success:function (args){
                // 反序列化 让后端发送过来的字符串变成js里面的对象
                {#args = JSON.parse(args)#}
                console.log(typeof args)  // 返回的是object格式
                // 可以针对状态码做一个判断
                if (args.code == 200){
                    $(\'#inp2\').val(args.data.username)  // js里面的object取值就可以用点语法
                }else{
                   alert(args.msg)
                }

AJAX发送json格式数据

需要将数据JSON.stringify(),contentType:\’application/json\’,序列化发送给后端。

sendjson.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>json数据</title>
    {% load static %}
 <link rel="stylesheet" type="text/css" href="{% static \'CSS/bootstrap.css\' %}"/>
    <script src="{% static \'JS/bootstrap.min.js\' %}"></script>
    <script src="{% static \'jQuery/jquery-3.6.0.min.js\' %}"></script>
</head>
<body>
<p>
    <input type="text" id="inp1">
</p>
<button id="btn" class="btn btn-primary">发送</button>
<input type="text" id="inp2">
<script>
    $(\'#btn\').click(function (){
        $.ajax({
            url:\'\',
            type:\'post\',
            data:JSON.stringify({\'inp1\':$(\'#inp1\').val()}),
            contentType:\'application/json\',
            success:function (res){
                $(\'#inp2\').val(res)
            }
        })
    })
</script>
</body>
</html>
views.py
def send_json(request):
	if request.is_ajax():
		bytes_data = request.body  # 接收到的是二进制数据
		str_data = bytes_data.decode(\'utf-8\')
		print(str_data)  # 转换成str类型
		d = json.loads(str_data) # 转换成字典
    print(type(d))  # <class \'dict\'>
		return HttpResponse(\'get it\')
  return render(request, \'sendjson.html\')

这里需要注意的是request.POST是没办法拿到json数据的,需要使用request.body进行接收,不过接收到的是二进制数据,如果想要进一步处理,需要将数据转成字符串。再反序列化成字典。

AJAX发送文件数据

Ajax上传文件数据需要借助于JS内置的FormData对象。

upload_file.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>上传文件</title>
    {% load static %}
    <link rel="stylesheet" href="{% static \'CSS/bootstrap.css\' %}">
    <script src="{% static \'jQuery/jquery-3.6.0.min.js\' %}"></script>
</head>
<body>
    <input type="text" id="inp1">
    <input type="file" id="inp2">
    <button class="btn-primary btn">上传</button>
    <script>
        $(\'.btn\').click(
            function (){
                // ajax上传文件需要借助内置的 FormData
                var FormDataObj = new FormData();
                // 1.添加普通数据
                FormDataObj.append(\'inp1\', $(\'#inp1\').val())
                // 2.添加文件数据
                FormDataObj.append(\'inp2\', $(\'#inp2\')[0].files[0])
                $.ajax({
                    url:\'\',
                    type:\'post\',
                    data:FormDataObj, // Django会自动识别FormData对象的数据

                    // 用FormData对象必须指定的参数
                    contentType:false, // 不指定编码格式
                    processData:false,  // 告诉浏览器不要再处理数据 原样发回来
                    success:function (res){

                    }
                })
            }
        )
    </script>
</body>
</html>
views.py
def upload_file(request):
    if request.is_ajax():
        print(request.POST)
        print(request.FILES)
    return render(request, \'upload_file.html\')
  
  # 输出结果
# <QueryDict: {\'inp1\': [\'11111\']}>
# <MultiValueDict: {\'inp2\': [<InMemoryUploadedFile: Snipaste_2021-08-13_15-15-54.png (image/png)>]}>

AJAX结合layer组件实现删除的二次确认

user_list.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户后台管理</title>
    {% load static %}
    <link rel="stylesheet" type="text/css" href="{% static \'CSS/bootstrap.css\' %}"/>
    <script src="{% static \'JS/bootstrap.min.js\' %}"></script>
    <script src="{% static \'jQuery/jquery-3.6.0.min.js\' %}"></script>
    <script src="{% static \'layer/layer.js\' %}"></script>
</head>
<body>
    <div class="container-fluid">
        <div class="row">
            <h1 class="text-center text-primary">用户后台管理</h1>
    <table class="table table-responsive table-striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>用户名</th>
                <th>密码</th>
                <th>注册时间</th>
                <th>最近登录</th>
                <th>是否锁定</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            {% for obj in user_info %}
                <tr>
                    <td>{{ obj.id }}</td>
                    <td>{{ obj.username }}</td>
                    <td>{{ obj.password }}</td>
                    <td>{{ obj.date_regis }}</td>
                    <td>{{ obj.last_login }}</td>
                    <td>{{ obj.is_locked }}</td>
                    <td>
{#                        a标签是自带跳转的这里我们需要阻止跳转 给它绑定事件 #}
                        <a href="javascript:;" class="btn btn-danger del" del_id="{{ obj.id }}" id="del_{{ obj.id }}">删除</a>
                        <a href="" class="btn btn-primary">修改</a>
                    </td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
        </div>
    </div>
    <script>
        $(\'.del\').click(function (){
            var id = $(this).attr(\'del_id\')
            label_del = $(this)  // 这时候的$(this)是a标签 赋值给label_del让后面能取到tr
            //询问框
            layer.confirm(\'确定删除?\', {
              btn: [\'确定\',\'取消\'] //按钮
            }, function(){
// 点击确认执行确认函数
                $.ajax({
                    url:\'\',
                    type:\'post\',
                    data:{\'id\':id},
                    success:function (res){
                        if (res.code==200){
                            layer.msg(res.msg, {icon: 1})
                            label_del.parent().parent().remove() // 直接在前端页面删除一行tr标签
                        }else {
                            layer.msg(res.msg, {icon: 1})
                        }
                    }
                })
            });
        })
    </script>
</body>
</html>
views.py
from app01 import models

def user_list(request):
  user_info = models.UserInfo.objects.all()
  if request.is_ajax():
    back_dic = {\'code\': 200, \'msg\': \'删除成功\'}
	# 获取前端传来的del_id
    del_id = request.POST.get(\'id\')
    models.UserInfo.objects.filter(pk=del_id).delete()
    return JsonResponse(back_dic)
  return render(request, \'user_list.html\', locals())

版权声明:本文为wuzhixian原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/wuzhixian/p/15172657.html