AJAX
一、什么是 JSON ?
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- JSON 是轻量级的文本数据交换格式
- JSON 独立于语言 *
- JSON 具有自我描述性,更易理解
* JSON 使用 JavaScript 语法来描述数据对象,但是 JSON 仍然独立于语言和平台。JSON 解析器和 JSON 库支持许多不同的编程语言。
合格的json对象(json只认双引的字符串格式):
["one", "two", "three"] { "one": 1, "two": 2, "three": 3 } {"names": ["张三", "李四"] } [ { "name": "张三"}, {"name": "李四"} ]
二、stringify与parse方法
JavaScript中关于JSON对象和字符串转换的两个方法:
JSON.parse(): 用于将一个 JSON 字符串转换为 JavaScript 对象(json只认双引的字符串格式)
JSON.parse('{"name":"Howker"}'); JSON.parse('{name:"Stack"}') ; // 错误 JSON.parse('[18,undefined]') ; // 错误
JSON.stringify(): 用于将 JavaScript 值转换为 JSON 字符串。
JSON.stringify({"name":"Tonny"})
三、AJAX和XML的比较
JSON 格式于2001年由 Douglas Crockford 提出,目的就是取代繁琐笨重的 XML 格式。
JSON 格式有两个显著的优点:书写简单,一目了然;符合 JavaScript 原生语法,可以由解释引擎直接处理,不用另外添加解析代码。所以,JSON迅速被接受,已经成为各大网站交换数据的标准格式,并被写入ECMAScript 5,成为标准的一部分。
XML和JSON都使用结构化方法来标记数据,下面来做一个简单的比较。
用XML表示中国部分省市数据如下:
<?xml version="1.0" encoding="utf-8"?> <country> <name>中国</name> <province> <name>黑龙江</name> <cities> <city>哈尔滨</city> <city>大庆</city> </cities> </province> <province> <name>广东</name> <cities> <city>广州</city> <city>深圳</city> <city>珠海</city> </cities> </province> <province> <name>台湾</name> <cities> <city>台北</city> <city>高雄</city> </cities> </province> <province> <name>新疆</name> <cities> <city>乌鲁木齐</city> </cities> </province> </country>
用JSON表示如下:
{ "name": "中国", "province": [{ "name": "黑龙江", "cities": { "city": ["哈尔滨", "大庆"] } }, { "name": "广东", "cities": { "city": ["广州", "深圳", "珠海"] } }, { "name": "台湾", "cities": { "city": ["台北", "高雄"] } }, { "name": "新疆", "cities": { "city": ["乌鲁木齐"] } }] }
由上面的两端代码可以看出,JSON 简单的语法格式和清晰的层次结构明显要比 XML 容易阅读,并且在数据交换方面,由于 JSON 所使用的字符要比 XML 少得多,可以大大得节约传输数据所占用得资源。
四、AJAX简介
AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML)。
AJAX 不是新的编程语言,而是一种使用现有标准的新方法。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
AJAX 不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。
- 同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
- 异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。
- 局部刷新页面:一个页面,不是整体刷新,而是页面的某个地方局部进行刷新
页面输入两个整数,通过AJAX传输到后端计算出结果并返回。
<!--ajaxsum--> <body> <input type="text" id="t1"> + <input type="text" id="t2"> = <input type="text" id="t3"> <p> <button id="b1">计算</button> </p> <script> $('#b1').on('click', function () { $.ajax({ // 向后端请求地址 url: '', // 向后端请求方式 type: 'post', // 向后端发送的数据 data: {'t1': $('#t1').val(), 't2': $('#t2').val()}, // 异步提交任务,通过回调函数接收后端发送的结果 success: function (data) { // data 形参代表的是异步提交返回的结果 //通过DOM操作 $("#t3").val(data); alert(data) } }) }) </script> </body>
# urls.py from app import views urlpatterns = [ url(r'^ajax/', views.ajax), ] # views.py def ajax(request): # 判断是否是ajax请求 print(request.is_ajax()) if request.method == 'POST': print(request.POST) # 获取前端数据 num1 = request.POST.get('t1') num2 = request.POST.get('t2') res = int(num1) + int(num2) return HttpResponse(res) return render(request, '01Ajax.html')
五、 contentType格式
form表单 默认的提交数据的编码格式是urlencoded
- urlencoded格式url: username=admin&password=123这种就是符合urlencoded数据格式,在浏览器控制台中可以查看到
- django后端针对username=admin&password=123的urlencoded数据格式会自动解析.将结果打包给request.POST 用户只需要从request.POST即可获取对应信息
form表单 ,formdata格式
- formdate格式:主要用来向后端传送文件,eg:视屏,文件,图片等
- django后端针对formdata格式类型数据 也会自动解析,但是不会将数据存放到方法request.POST中而是给你放到了request.FILES中
ajax编码格式
- ajax默认的提交数据的编码格式是urlencoded(username=jason&password=123)
总结
1. django后端针对不同的编码格式数据 会有不同的处理机制以及不同的获取该数据的方法
2. 前后端在做数据交互的时候 一定一定要标明你所发的的数据到底是什么格式
3. 你所传数据是什么格式 你就应该准确无误告诉别人是什么格式
六、AJAX传送Json格式亲后台交互
<!--ajaxsum--> <body> <button id='b1'>Json前后端交互</button> <script> $('#b1').on('click', function () { $.ajax({ // 向后端请求的地址 url: '', // 请求类型 type: 'post', // 提交数据格式 contentType: 'application/json', // 传送json字符串 data: JSON.stringify({'username': 'randy', 'password': '123'}), // 回调函数 success: function (data) { alert('我是后端返回来的json对象') back_dic = JSON.stringify(data); alert(back_dic); }, }) }) </script> </body>
# urls.py from app import views urlpatterns = [ url(r'^Ajax_Json/', views.Ajax_Json), ] # views.py def Ajax_Json(request): if request.method == 'POST': print(request.POST) # 获取前端数据 print(request.body) # 结果b'{"username":"randy","password":"123"}' res_json = request.body str_json = str(res_json, encoding='utf8') print(str_json) dic_json = json.loads(str_json) print(dic_json, type(dic_json)) # 返回前端json对象 back_dic = {'code': 'sucesss', 'msg': "后台已经接收到"} return JsonResponse(back_dic) return render(request, '02Ajax_Json.html')
django后端针对json格式的数据 不会自动帮你解析 会直接原封不动的给你放到request.body中,可以手动处理 获取数据
注意:
指定contentType参数
contentType:'application/json',
要将你发送的数据 确保是json格式
data:JSON.stringify({'username':'jason','password':'123'})
七、AJAX传文件
<!--ajaxfile--> <body> <input type="text" name="username" id="t1"> <input type="text" name="password" id="t2"> <input type="file" name="myFile" id="t3"> <button id="b1">上传文件</button> <script> // 上传文件 $('#b1').on('click', function () { // 1 生成一个formdata对象 var myFormdata = new FormData(); alert(myFormdata); // 2 向对象中添加普通键值 myFormdata.append('username', $('#t1').val()); myFormdata.append('password', $("#t2").val()); // 3 向对象中添加文件对象 // a 先通过jquery查找到文件标签 // b 将jquery对象转换成js对象 // c 利用原生js对象的方法,直接获取文件内容 myFormdata.append('myFile', $('#t3')[0].files[0]); $.ajax({ url: '', // 默认当前页 type: 'post', // 直接放入对象 data: myFormdata, // ajax传文件,一定要指定两个关键性参数 contentType: false,// 不用任何编码,因为formdata对象自带编码,django能够识别该对象 processData: false, // 告诉浏览器不要处理我的数据,直接发送就可以 success: function (data) { alert(data) } }) }) </script> </body>
# urls.py from app import views urlpatterns = [ url(r'^Ajax_File/', views.Ajax_File), ] # views.py def Ajax_File(request): if request.method == 'POST': # 获取数据 print(request.POST) # 获取文件 print(request.FILES) # 保存文件 with open('file.jpg', 'wb') as f: for chunk in request.FILES.get("myFile").chunks(): f.write(chunk) # 响应前端 return HttpResponse('success') return render(request, '03Ajax_File.html') """ ajax传文件需要注意的事项 1.利用formdata对象 能够简单的快速传输数据 (普通键值 + 文件) 2.有几个参数 data:formdata对象 contentType:false processData:false """
总结:
- 实例化:myFormdata= new FormData()对象
- 添加值: myFormdata.append('username', $('#t1').val());
- 添加文件:myFormdata.append('myFile', $('#t3')[0].files[0]);
- 先通过jquery查找到文件标签
- 将jquery对象转换成js对象
- 利用原生js对象的方法,直接获取文件内容
- 直接传送对象: data:formdata对象
- 设置两个参数
- contentType:false // 不用任何编码,因为formdata对象自带编码,django能够识别该对象
- processData:false // 告诉浏览器不要处理我的数据,直接发送就可以
八、序列化组件
<body> {% for user in user_list %} {{ user }} <br> {% endfor %} </body>
# urls.py from app import views urlpatterns = [ url(r'^serializer/', views.serializer), ] # views.py # 导入模块 from django.core import serializers from app import models def serializer(request): user_obj = models.Userinfo.objects.all() # 序列化对象 user_list = serializers.serialize('json', user_obj) user_list = json.loads(user_list) print(user_list, type(user_list)) return render(request, '04serializer.html', locals())
总结:
- 首先的导入:
from django.core import serializers
- 调用方法序列化
- 序列化的结果是字符串
九、ajax和sweetalert实现动态框
sweetalert下载链接:https://lipis.github.io/bootstrap-sweetalert/
使用方法:下载使用dist文件下面的css.js
<head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script> {% load static %} <link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}"> <script src="{% static 'dist/sweetalert.min.js' %}" s></script> <style> div.sweet-alert h2 { padding-top: 10px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-lg-offset-2"> <h1 class="text-center">管理数据</h1> <table class="table table-striped table-hover table-bordered"> <thead> <tr> <th>编号</th> <th>用户名</th> <th>密码</th> <th>性别</th> <th>操作</th> </tr> </thead> <tbody> {% for user in usre_obj %} <tr> <td>{{ forloop.counter }}</td> <td>{{ user.username }}</td> <td>{{ user.password }}</td> <td>{{ user.get_gender_display }}</td> <td> <a href="#" class="btn btn-primary btn-sm">编辑</a> <a href="#" class="btn btn-danger btn-sm cnacel delete_id={{ user.pk }}">删除</a> </td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> <script> $(".cnacel").on('click', function () { var $btn = $(this); swal({ title: "你确定要删吗?", text: "你要是删了,你就准备好跑路吧!", type: "warning", showCancelButton: true, confirmButtonClass: "btn-danger", confirmButtonText: "对,老子就要删!", cancelButtonText: "可怕!", closeOnConfirm: false, showLoaderOnConfirm: true }, function () { $.ajax({ url: '', type: "post", data: {'delete_id': $btn.attr('delete_id')}, success: function (data) { if (data.code == 1000) { swal("删除!", "文件已删除", "success"); $btn.parent().parent().remove() } else { swal("取消", "太危险了 :)", "error"); } } }); }); }) </script> </body>
# urls.py from app import views urlpatterns = [ url(r'^sweetalert/', views.sweetalert), ] # views.py def sweetalert(request): if request.method == 'POST': print(request.POST) delete_id = request.POST.get('delete_id') print(delete_id) models.Userinfo.objects.filter(pk=delete_id).delete() back_dic = {'code': 1000, 'mst': ''} return JsonResponse(back_dic) usre_obj = models.Userinfo.objects.all() # for user in usre_obj: # print(user.username) return render(request, '05sweetalert使用.html', locals())