ajax
一、Ajax
'''页面不刷新的情况下可以与后端进行数据交互 异步提交 局部刷新 eg:码云用户注册 无序点击按钮内部也可以完成数据交互 ajax不是一门全新知识 本质就是一些js代码 我们学习ajax直接使用jQuery封装之后的版本(语法更简单) 使用ajax的前提必须要引入jQuery文件''' # ajax和form的区别 ajax提交数据页面不用刷新 原始数据还在 处理数据的过程中不影响页面其他操作 form表单提交数据页面刷新 原始数据不在 并且处理数据的过程中无法做其他操作
1.代码实现
'''eg:页面上放三个input框 前面两个输入数字 第三个计算两个数字的和 按完按钮之后页面不能刷新 而且框中的数字不能消失''' # form表单是实现不了的, form表单已提交就会直接刷新页面 $('#btn').click(function (){ # 给按钮绑定点击事件 # 获取两个框里面的数据 let i1Val = $('#i1').val(); let i2Val = $('#i2').val(); # 发送ajax请求传输数据 $.ajax({ url:'', # 不写默认就是当前页面所在的地址 type:'post', # 指定当前请求方式 data:{'i1':i1Val,'i2':i2Val}, # 请求携带的数据 后端通过K获取值 success:function (arg){ # 异步回调函数 后端有回复自动触发 $('#i3').val(arg) } }) }) # 这样就可以在页面实现不刷新 给后端提交数据
2.基础语法
$.ajax({ url:'', # 控制数据的提交地址 不写就是默认给当前地址提交 type:'', # 控制请求方式(默认get请求) data:{}, # 组织提交的数据 后端按照K取值 success:function(形参){ # 形参就是接收后端返回的值 # 异步回调函数 可以根据后端返回的值操作 } })
二、数据编码格式
# 当我们进行前后端文件传输的时候是依据数据的编码格式的 # form表单修改编码格式的属性为:enctype # ajax修改编码格式的属性为:Content-Type ''' 请求体中携带编码方式 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 django针对不同编码方式对应的数据格式会采用不同的处理策略 ''' # form表单默认发送的编码格式: Content-Type: application/x-www-form-urlencoded 数据格式:username=jason&password=123 django后端会自动处理到:request.POST # form表单发送文件 Content-Type:multipart/form-data 数据格式:隐藏了不让看 django后端会自动处理:request.POST request.FILES # ajax默认的编码格式 Content-Type: application/x-www-form-urlencoded 数据格式:username=jason&password=123 django后端会自动处理到:request.POST '''ajax和form表单默认的编码格式都是urlencoded form表单发送文件需要把编码格式修改为 multipart/form-data form表单不能传输json格式数据 需要使用ajax '''
三、ajax携带文件数据
# form表单发送文件数据就只需要把编码格式修改为 multipart/form-data 那ajax怎么携带文件数据呢? # 前端 $('#d3').click(function () { # 产生一个对象 let formData = new FormData() # 添加普通数据 formData.append('username',$('#d2').val()) # 添加文件数据 formData.append('file',$('#d1')[0].files[0]) # 后端就是根据前面字符串提取数据 第一个索引变成标签对象 如果是多个文件第二个索引可以不用加 $.ajax({ url:'', type:'post', data:formData, # 添加文件数据需要写两个固定参数 contentType:false, # 不用任何编码 processData: false, # 不处理数据对象 success:function (args){ } }) }) # 后端 username = request.POST.get('username') file = request.FILES.get('file') # 后端还是一样的
四、ajax发送json格式数据
# 前后端交互数据一般都是使用json格式数据 form表单是发送不了json格式数据的 只能使用ajax # 前端: $('#d1').click(function (){ $.ajax({ url: '', type: 'post', # 不写默认是get请求 contentType:'application/json', # 不写默认是urlencoded编码 data: JSON.stringify({'name': 'jason', 'pwd': 123}), # 直接发送json格式数据 success: function (args) { } }) }) # 后端: '''django后端针对json格式的数据不会做任何的处理 就在request.body内 需要我们自行处理''' print(request.POST, request.FILES) # <QueryDict: {}> <MultiValueDict: {}> # 所以POST和FILES是拿不到前端发送过来的json格式数据的 # 需要在request.body中获取 print(request.body) # b'{"name":"jason","pwd":123}' 是bytes类型 data_json = request.body data = json.loads(data_json) # json自带解码功能 print(data, type(data)) # {'name': 'jason', 'pwd': 123} <class 'dict'>
五、回调函数
# 后端跟ajax交互 不应该再返回一个页面 而是返回一个json格式数据 # 向我们之前学习的三板斧render、redirect、HttpResponse 前两者都是返回一个页面 这样就算返回了前端也不会跳转 HttpResponse返回一个字符串其实也会被回调函数的参数接收 # 现在我们在后端发送给前端json格式数据 # 后端 return HttpResponse(json.dumps({'name': 'jason', 'pwd': 123})) # 前端 console.log(args) # {"name": "jason", "pwd": 123} console.log(typeof args) # string # 我们发现后端发送过来的json格式数据是不会帮我们反序列化的 success: function (args) { let Data = JSON.parse(args) # 需要我们手动反序列化 console.log(typeof Data) # object console.log(Data) # {name: 'jason', pwd: 123} console.log(Data.name) # jason } # 但是这是使用HttpResponse返回的 现在我们使用JsonResponse返回看看 # 后端 return JsonResponse({'name': 'jason', 'pwd': 123}) # 前端 success: function (args) { console.log(typeof args) # object console.log(args) # {name: 'jason', pwd: 123} console.log(args.name) # jason } '''
使用JsonResponse返回数据前端是会自动帮我们反序列化的 因为HttpResponse返回的其实就是一个字符串对象 前端所以不会反序列化 而JsonResponse返回的是一个json格式数据 前端就会帮我们自动反序列化 而如果想让HttpResponse自动反序列化需要加一个参数 dataType:'JSON' dataType:'JSON', success: function (args) { console.log(typeof args) // object console.log(args) // {name: 'jason', pwd: 123} console.log(args.name) // jason } '''
六、序列化
# 当我们以后前后端分离会后 前端是不识别 django ORM产生的Queryset数据对象的 所以还是需要json格式数据 # 后端: data_list = [] # 数据格式为 [{}, {}, {}] user_queryset = models.Book.objects.filter() for obj in user_queryset: data_dict = {} data_dict['pk'] = obj.pk data_dict['title'] = obj.title data_dict['publish'] = obj.publish.name data_list.append(data_dict) return HttpResponse(json.dumps(data_list)) # 这样有点代码冗余 django自带了序列化组件 # 后端: from django.core import serializers user_list = models.Book.objects.filter() res = serializers.serialize('json', user_list) # 第一个参数决定以什么方式序列化数据 return HttpResponse(res) # 可以去bejson官网看下我们发送给前端的json格式的数据张啥样 这就是以后如果前后端分离 我们需要发送给前端的json格式数据
七、作业
# 使用sweetalert做删除二次确认 后端: def delete(request): if request.method == 'POST': data_id = request.POST.get('delete_id') models.Book.objects.filter(pk=data_id).delete() return HttpResponse('删除成功') # 前端 <a href="#" class="btn btn-danger btn-xs subBtn" delete_id = {{ book_obj.id }}>删除</a> $('.subBtn').click(function (){ let dataEle = $(this).attr('delete_id') # 获取删除的书籍id swal({ title: "你确定要删除把", text: "你在想想吧", icon: "warning", buttons: ['取消', '确定'], dangerMode: true, }) .then((willDelete) => { if (willDelete) { $.ajax({ url:'/delete/', # 朝删除网址发送 type:'post', data:{'delete_id':dataEle}, success:function (args){ swal(args, {icon: "success",}) } }) } else { swal("不删就好"); } }); })