11_07、Ajax
一、什么是Ajax
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
AJAX除了异步的特点外,还有一个就是:浏览器页面局部刷新;(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
场景:
优点:
- AJAX使用Javascript技术向服务器发送异步请求
- AJAX无须刷新整个页面
二、基于jquery的Ajax实现
1、什么是基于jQuery的ajax
ajax在js中有自己的原生写法,但是如果我们使用js的原生写法操作ajax,比较麻烦。
jQuery是js的封装库,我们通过封装后的jQuery操作ajax,书写简单方便
实例演示——基于jQuery的ajax实现计算器
2、效果展示:
3、思路:
1.浏览器中输入指令,点击计算按钮
2.把输入的指令传入服务端计算,并把计算结果返回给浏览器
3、浏览器获取后端传回的结果,并展示
4、具体操作
views.py(后端)
def my_ajax(request): if request.method == 'POST' and request.is_ajax(): print(request.POST) # <QueryDict: {'d1': ['1'], 'd2': ['1']}> d1 = request.POST.get('d1') # 接收前端传入的d1,字符串类型 d2 = request.POST.get('d2') # 接收前端传入的d2,字符串类型 d3 = int(d1) + int(d2) return HttpResponse(d3) # 把结果返回给前端 return render(request, 'my_ajax.html')
路由
from ajax实例演示 import views urlpatterns = [ url(r'^ajax/', views.my_ajax), ]
my_ajax.html(前端)
<body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <input type="text" id="d1"> + <input type="text" id="d2"> = <input type="text" id="d3"> <button class="btn btn-success">计算</button> </div> </div> </div> <script> $('.btn').click(function () { var d1 = $('#d1').val(); // 取得输入的d1值 var d2 = $('#d2').val(); // 取得输入的d2值 $.ajax({ // 1、朝后端提交的地址 url: '/ajax/', // 不指定默认朝当前地址提交 // 2、指定请求方式 type: 'post', // 默认不写是get请求 // 3、指定要传入的参数 data: {d1: d1, 'd2': d2}, // 把d1、d2的值赋值给d1、d2,k值可以加'',也可以不加''。 // 4、回调函数,接收后端返回的结果 success: function (res) { console.log(res) // 打印后端返回的结果 $('#d3').val(res) // 把后端返回的结果设置为前端中d3框的值 } }) }) </script> </body>
三、后端向前端ajax传值的三种方式
上述案例中,后端向前端返回的数据是python字符串格式。
但是在跨语言传输过程中,为了保证数据的安全和准确性,我们一般都会把要传输的数据序列化
这里提供三种思路:
方式一:
后端中序列化,前端中反序列化
'''views.py''' def my_ajax(request): if request.method == 'POST' and request.is_ajax(): print(request.POST) # <QueryDict: {'d1': ['1'], 'd2': ['1']}> d1 = request.POST.get('d1') # 接收前端传入的d1,字符串类型 d2 = request.POST.get('d2') # 接收前端传入的d2,字符串类型 d3 = int(d1) + int(d2) # 序列化 import json # 导入json json_str = json.dumps(d3) # 序列化d3 return HttpResponse(json_str) # 把序列化后的结果返回给前端 return render(request, 'my_ajax.html')
HTML文件
<script> $('.btn').click(function () { var d1 = $('#d1').val(); // 取得输入的d1值 var d2 = $('#d2').val(); // 取得输入的d2值 $.ajax({ // 1、朝后端提交的地址 url: '/ajax/', // 不指定默认朝当前地址提交 // 2、指定请求方式 type: 'post', // 默认不写是get请求 // 3、指定要传入的参数 data: {d1: d1, 'd2': d2}, // 把d1、d2的值赋值给d1、d2,k值可以加'',也可以不加''。 // 4、回调函数,接收后端返回的结果 success: function (res) { console.log(res) // 打印后端返回的结果——json字符串:8 res=JSON.parse(res) // 把返回的json字符串反序列化 console.log(res,typeof res) // 结果:2 'number' $('#d3').val(res) // 把反序列化后的结果设置为前端中d3框的值 } }) }) </script>
方式二:
后端直接返回json对象,前端直接取值,无需反序列化
'''views.py''' from django.http import JsonResponse def my_ajax(request): if request.method == 'POST' and request.is_ajax(): print(request.POST) # <QueryDict: {'d1': ['1'], 'd2': ['1']}> d1 = request.POST.get('d1') # 接收前端传入的d1,字符串类型 d2 = request.POST.get('d2') # 接收前端传入的d2,字符串类型 d3 = int(d1) + int(d2) d3 = {'d3': d3} return JsonResponse(d3) # 利用JsonResponse直接返回序列化对象 return render(request, 'my_ajax.html')
<script> $('.btn').click(function () { var d1 = $('#d1').val(); // 取得输入的d1值 var d2 = $('#d2').val(); // 取得输入的d2值 $.ajax({ // 1、朝后端提交的地址 url: '/ajax/', // 不指定默认朝当前地址提交 // 2、指定请求方式 type: 'post', // 默认不写是get请求 // 3、指定要传入的参数 data: {d1: d1, 'd2': d2}, // 把d1、d2的值赋值给d1、d2,k值可以加'',也可以不加''。 // 4、回调函数,接收后端返回的结果 success: function (res) { console.log(res) // 打印后端返回的结果——json对象:{d3: 2} res = res.d3 $('#d3').val(res) // 把反序列化后的结果设置为前端中d3框的值 } }) }) </script>
方式三:
view.py文件
在前端中设定后端返回值为json
def my_ajax(request): if request.method == 'POST' and request.is_ajax(): print(request.POST) # <QueryDict: {'d1': ['1'], 'd2': ['1']}> d1 = request.POST.get('d1') # 接收前端传入的d1,字符串类型 d2 = request.POST.get('d2') # 接收前端传入的d2,字符串类型 d3 = int(d1) + int(d2) return HttpResponse(d3) # 直接传入,不需要序列化 return render(request, 'my_ajax.html')
<script> $('.btn').click(function () { var d1 = $('#d1').val(); // 取得输入的d1值 var d2 = $('#d2').val(); // 取得输入的d2值 $.ajax({ // 1、朝后端提交的地址 url: '/ajax/', // 不指定默认朝当前地址提交 // 2、指定请求方式 type: 'post', // 默认不写是get请求 // 3、指定要传入的参数 data: {d1: d1, 'd2': d2}, // 把d1、d2的值赋值给d1、d2,k值可以加'',也可以不加''。 // 4、指定后端返回的数据类型 dataType:'json', // 5、回调函数,接收后端返回的结果 success: function (res) { console.log(res) // 2 res = JSON.parse(res) $('#d3').val(res) // 把反序列化后的结果设置为前端中d3框的值 } }) }) </script>
四、前端Ajax向后端发送数据
1、ajax发送json格式数据
# ajax发送json数据 import json def my_json(request): if request.method == 'POST' and request.is_ajax(): print(request.POST) # <QueryDict: {}> POST接收的是urlencode类型,所以不能用POST接收 print(request.body) # b'{"d1":"1","d2":"1"}' body接收的是json类型 json_bytes = request.body json_str = json_bytes.decode('utf8') # 给接收的json数据解码,转换成json字符串 print(json_str, type(json_str)) # {"d1":"1","d2":"1"} <class 'str'> # 把json字符串转换成json对象 res_json = json.loads(json_str) # 把json字符串转换成json对象:字典类型 print(res_json, type(res_json)) # {'d1': '1', 'd2': '1'} <class 'dict'> # 字典取值 d3 = int(res_json['d1']) + int(res_json['d2']) return HttpResponse(d3) # 利用JsonResponse直接返回序列化对象 return render(request, 'json.html')
<div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <input type="text" id="d1"> + <input type="text" id="d2"> = <input type="text" id="d3"> <button class="btn btn-success">计算</button> </div> </div> </div> <script> $('.btn').click(function () { var d1 = $('#d1').val(); // 取得输入的d1值 var d2 = $('#d2').val(); // 取得输入的d2值 $.ajax({ // 1、朝后端提交的地址 url: '/json/', // 不指定默认朝当前地址提交 // 2、指定请求方式 type: 'post', // 默认不写是get请求 // 3、指定要传入的参数 data: JSON.stringify({'d1': d1, 'd2': d2}), // 前端数据json序列化传入 // 4、设置提交的数据类型是json contentType:'application/json', // 5、指定后端返回的数据类型 dataType: 'json', // 5、回调函数,接收后端返回的结果 success: function (res) { console.log(res) // 2 res = JSON.parse(res) $('#d3').val(res) // 把反序列化后的结果设置为前端中d3框的值 } }) }) </script>
2、ajax发送文件数据
# ajax发送文件数据 def my_file(request): if request.method == 'POST' and request.is_ajax(): print(request.POST) # 接收传来的数据 <QueryDict: {'username': ['LY']}> print(request.FILES) # 接收传来的文件 <MultiValueDict: {'myfile': [<InMemoryUploadedFile: 微信截图_20220313203813.png (image/png)>]}> # 获取文件对象 myfile_obj = request.FILES.get('myfile') # 存储文件 return render(request, 'my_file.html')
<body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <input type="file" id="myfile"> <input type="text" id="username"> <button class="btn btn-success">提交</button> </div> </div> </div> <script> $('.btn').click(function () { // 1、获取数据 var myfile = $('#myfile')[0].files[0] // 获取文件数据 var username = $('#username').val() // 获取普通数据 // 2、ajax发送文件数据需要借助formdata对象 var myFormDataObj = new FormData ///3、借助formdata追加数据 myFormDataObj.append('myfile', myfile) // 追加文本数据 myFormDataObj.append('username', username) // 追加普通数据 $.ajax({ // 1、朝后端提交的地址 url: '/file/', // 不指定默认朝当前地址提交 // 2、指定请求方式 type: 'post', // 默认不写是get请求 // 3、指定要传入的参数 data: myFormDataObj, // 把追加完毕的对象放入data // 4、设置提交的数据类型是json {#contentType:'application/json', // 默认就是json#} // 5、发送文件数据需要指定两个参数 contentType: false, // 告诉浏览器不要修改提交数据的编码格式 processData: false, // 告诉浏览器不要对提交的数据进行任何更改 // 6、指定后端返回的数据类型 dataType: 'json', // 7、回调函数,接收后端返回的结果 success: function (res) { console.log(res) // 打印后端返回的结果,json字符串 } }) }) </script>
五、ajax实现删除的二次确认
# 创建表单
class Del(models.Model): title = models.CharField(max_length=64, verbose_name='图书标题') price = models.DecimalField(max_digits=8, decimal_places=2, verbose_name='价格')
# 后端
def my_ajax(request): book_list = models.Del.objects.all() if request.is_ajax(): id = request.POST.get('id') models.Del.objects.filter(pk=id).delete() return JsonResponse({'code': 200, 'msg': '删除'}) return render(request, 'del.html', locals())
# 前端
<body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1>ajax的二次删除——弹窗</h1> <table class="table table-hover table-striped"> <thead> <tr> <td>序号</td> <td>书籍</td> <td>价格</td> <td>操作</td> </tr> </thead> <tbody> {% for book in book_list %} <tr> <td>{{ book.pk }}</td> <td>{{ book.title }}</td> <td>{{ book.price }}</td> <td> <a href="#" class="btn btn-danger " book_id="{{ book.pk }}">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> $('.btn').click(function () { var id = $(this).attr('book_id'); layer.confirm('是否确认删除?', { btn: ['确认', '取消'] //按钮 }, function () { $.ajax({ url: '', type: 'post', data: {'id': id}, success: function (res) { if (res.code == 200) { layer.msg(res.msg, {icon: 1}, function () { location.reload(); }); } else { layer.msg(res.msg,) } } }) },); }) </script> </body>
补充:
1、删除时自动刷新页面的四种解决方式:
1.删除href
<a class="btn btn-danger " book_id="{{ book.pk }}">删除</a>
2.添加#
<a href="#" class="btn btn-danger " book_id="{{ book.pk }}">删除</a>
3.事件函数
function() {return false}
4.事件函数
function(e) {e.preventDefault()}
2、删除成功后需要手动刷新的两种解决方式:
1.刷新页面
function () {location.reload()
2.删除form表单中的tr
<tr class='form_{{book.pk}}'>
<td>{{ book.pk }}</td>
<td>{{ book.title }}</td>
<td>{{ book.price }}</td>
<td>
<a href="#" class="btn btn-danger " book_id="{{ book.pk }}">删除</a>
</td>
</tr>
function () {$('.form_' + id).remove()}
六、Django自带的序列化器
from django.core import serializers def my_ajax(request): book_list = models.Del.objects.all() return serializers.serialize('json', book_list)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通