一 AJAX简介
AJAX(Asynchronous JavaScript And XML)异步的JavaScript和XML。
AJAX最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
- 同步交互:客户端发送一个请求,需要等待服务器响应之后才能发送第二个请求。
- 异步交互:客户端发送请求后,不需要等待响应结果就可以发送其他请求。
示例:在前端页面输入两个数字,通过Ajax发送到后端计算后返回到前端展示。
templates/sum.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">
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<button class="btn btn-success btn-xs" id="d4">计算</button>
</div>
</div>
</div>
<script>
<!--给计算按钮绑定一个点击事件-->
$('#d4').click(function () {
$.ajax({
url: '', <!--提交数据的路径 相当于form表单中的action参数-->
type: 'post', <!--指定提交方式-->
data: {'i1': $('#d1').val(), 'i2': $('#d2').val()},<!--提交给后端的数据-->
success:function (args) {<!--回调函数 参数args就是后端返回的数据-->
$('#d3').val(args)
}
})
})
</script>
</body>
urls.py 代码:
path('sum/', views.two_sum)
views.py 代码
def two_sum(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
res = int(i1) + int(i2)
return HttpResponse(str(res))
return render(request, 'sum.html')
绑定一个失去焦点事件:
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<input type="text" id="d1" class="c1"> + <input type="text" id="d2" class="c1"> = <input type="text" id="d3">
</div>
</div>
</div>
<script>
$('.c1').blur(function () {
$.ajax({
url: '',
type: 'post',
data: {'i1': $('#d1').val(), 'i2': $('#d2').val()},
success:function (args) {
$('#d3').val(args)
}
})
})
</script>
</body>
def two_sum(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
if i1 and i2:
res = int(i1) + int(i2)
return HttpResponse(str(res))
else:
return HttpResponse('输入不完整')
return render(request, 'sum.html')
二 数据编码格式
可以朝后端发送post请求的方式有两种,form表单和Ajax请求。
前后端传输数据的编码格式:
- urlencoded
- formdata
- json
2.1 form表单中
- 默认的数据编码是urlencoded
- 数据格式:username=jasper&password=123
- Django后端会针对符合urlencoded编码格式的数据帮你解析封装到request.POST中
- 如果编码格式改为formdata,那么针对普通的键值对还是解析到request.POST中,而文件则解析到request.FILES中。
- form表单无法发送json格式数据
2.2 Ajax中
- 默认编码也是urlencoded
- 数据格式:username=jasper&pwd=123
- Django后端会针对符合urlencoded编码格式的数据帮你解析封装到request.POST中
Ajax发送json格式数据
- contentType参数指定为application/json
- 数据必须是json格式的
- Django后端不会处理json格式的数据,需要到request.body获取并处理
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">ajax测试:
<input type="text" id="d1" name="test">
<button class="btn btn-success btn-group-sm" id="d2">提交ajax请求</button>
</div>
</div>
</div>
<script>
$('#d2').click(function () {<!--给input标签绑定一个单击事件-->
$.ajax({
url:'',
type:'post',
data: JSON.stringify({'input':$('#d1').val()}),<!--数据必须是json格式-->
contentType:'application/json',<!--数据格式必须是'application/json'-->
success: function (args) {
console.log(this.data, typeof this.data)
}
})
})
</script>
</body>
path('ajax/', views.ajax),
def ajax(request):
if request.method == "POST":
print(request.POST) # <QueryDict: {}>
print(request.FILES) # <MultiValueDict: {}>
print(request.body) # b'{"data":"ajax\xe6\xb5\x8b\xe8\xaf\x95"}'
import json
res = json.loads(request.body)
print(res, type(res)) # {'data': 'ajax测试'} <class 'dict'>
return render(request, 'ajax.html')
三 Ajax携带文件数据
Ajax发送文件需要借助js内置对象FromData
<body>
<div class="row">
<div class="col-md-8">
用户名:<input type="text" name="username" id="name">
密码:<input type="password" name="password" id="pwd">
<input type="file" name="file" id="file">
<button class="btn btn-success" id="d1">提交</button>
</div>
</div>
<script>
$('#d1').click(function () {
// 1. 先产生一个FormData对象
let fromData = new FormData();
// 2. 添加普通键值对
fromData.append('username', $('#name').val())
fromData.append('password', $('#pwd').val())
// 3. 添加文件对象
fromData.append('file', $('#file')[0].files[0])
console.log(111)
// 4. 将对象通过ajax发送给后端
$.ajax({
url: '',
type: 'post',
data: fromData, //数据就是对象
contentType: false, //不需要任何数据格式 Django后端会自动识别formData对象
processData: false, //不对数据进行任何处理
success: function (args) {
}
})
})
</script>
</body>
def ajax_file(request):
if request.method == 'POST':
print(request.POST) # <QueryDict: {'username': ['17391767493'], 'password': ['111']}>
print(request.FILES)
# <MultiValueDict: {'file': [<InMemoryUploadedFile: 国庆作业安排.xls (application/vnd.ms-excel)>]}>
return render(request, 'file.html')
四 回调函数
- 后端在跟Ajax交互时,应该返回json格式字符串而不是其他的东西。
- 前端针对HttpResponse和JsonResponse返回的数据处理策略不同。前者不会自动反序列化,而后者会自动反序列化。如果想让前者也能自动反序列化,需要加一个参数dataType:‘JSON’
<body>
<input type="text" id="d1">
<button class="btn" id="d2">ajax请求</button>
<script>
$('#d2').click(function () {
$.ajax({
url:'',
type:'post',
data: '',
success:function (args) {
console.log(args, typeof args)
$('#d1').val(args)
}
})
})
</script>
</body>
def callback(request):
if request.method == 'POST':
return HttpResponse("{'name': 'jasper', 'age': 18}")
return render(request, 'callback.html')
def callback(request):
if request.method == 'POST':
from django.http import JsonResponse
return JsonResponse({'name': 'jasper', 'age': 18})
return render(request, 'callback.html')
五 序列化
首先,从djang.core导入它,然后调用它的serialize方法,这个方法至少接收两个参数,第一个是你要序列化成为的数据格式,这里是‘jsonl’,第二个是要序列化的数据对象,数据通常是ORM模型的QuerySet,一个可迭代的对象。
def ser(request):
user_list = models.Book.objects.all()
from django.core import serializers
res = serializers.serialize('json', user_list)
return HttpResponse(res)