jQuery Ajax
Ajax介绍
Ajax
能够在不刷新页面的情况下发送并接受后端数据。
是现在Web
开发中大量使用的一种技术。
这里介绍一下jQuery
中的Ajax
。
数据格式
在前后端交互中,总共有三种格式。不同的格式对应后端不同的框架中有不同的处理方式,这里以Django
为例。
如果要查看你发送数据的格式,可在请求头中有一个Content-Type
中进行查看。
urlencoded
urlencoded
是默认的编码格式,不论是使用form
表单,或者是ajax
。
当你使用此种编码格式时,将不能上传文件,并且数据格式为username=xxx&password=xxx
。
在Django
中,会将此种编码格式存放至响应的请求方式中,如request.GET/request.POST
。
multipart/form-data
multipart/form-data
允许上传文件,在Django
中将会把文件放在request.FILES
中,而其他数据则会放在request.POST
中。
注意:multipart/form-data
只能由POST
进行上传。
application/json
json
格式常见于ajax
发送请求中,特别是前后端分离项目。这种格式非常常见,而后端如果是使用Django
,那么Django
会将数据保存在request.body
中。
并且我们可以在视图函数中使用request.is_ajax()
方式来判断,前端是不是通过ajax
发送的数据。
需要注意的是json
格式的数据只能通过POST
进行发送,因为GET
方式是会将数据放在地址栏的。
import json
if request.is_ajax():
data = request.body
json.loads(data)
基本使用
jQuery
中封装的Ajax
使用十分便捷,以下操作将演示如何发送Ajax
请求并且让后端返回相应的数据。
注意事项
1.前端传递参数中,不允许出现对象嵌套的形式。如
{"k1":{"k1-1":v1}}
2.如果前端传递的是一个
Array
,如{"k1":[1,2,3,4]}
则需要添加一个属性traditional:true
,否则后端将接收不到该参数。(实际上接受的时候要使用request.POST.get("k1[]")
)来进行接受,这是有问题的。
<QueryDict: {'k1[]': ['1', '2', '3', '4']}>
。
$.ajax({
url: "http://127.0.0.1:8000/", // 发送的路径
type: "post", // 发送方式
dataType: 'JSON', // 反序列化
data:{v1,v2}, // 发送的数据
success: (res) => { // 成功获取到后端返回结果的回调函数
res_ele.value = res;
},
error:()=>{ // 发送失败的回调函数
console.log("失败");
}
})
<body>
<p><input type="text"></p>
<p><input type="text"></p>
<p><input type="text" readonly style="background-color: #eee;"></p>
<p><button type="button">提交</button></p>
</body>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<script>
window.onload = (() => {
document.querySelector("button").addEventListener("click", (ele) => {
let v1 = document.querySelectorAll("input")[0].value;
let v2 = document.querySelectorAll("input")[1].value;
let res_ele = document.querySelectorAll("input")[2];
$.ajax({
url: "http://127.0.0.1:8000/", // 发送的路径
type: "post", // 发送方式
dataType: 'JSON', // 反序列化
data:{v1,v2}, // 发送的数据
success: (res) => { // 成功获取到后端返回结果的回调函数
res_ele.value = res;
},
error:()=>{ // 发送失败的回调函数
console.log("失败");
}
})
})
})
</script>
def test(request):
if request.method == "POST":
v1 = request.POST.get("v1")
v2 = request.POST.get("v2")
res = int(v1) + int(v2)
return JsonResponse(res,safe=False)
return render(request,"base.html",locals())
发送Json
如果前端要发送JSON
格式的数据,则需要声明数据格式为JSON
。
$.ajax({
url: "http://127.0.0.1:8000/", // 发送的路径
type: "post", // 发送方式
dataType: 'JSON', // 反序列化
data:JSON.stringify({"name":"Yunya","age":18}), // 发送的数据,注意,这里一定要序列化,因为已经声明了。
contentType:'application/json', // 声明发送数据格式
success: (res) => {
console.log(res);
},
error:()=>{
console.log("失败");
}
})
注意:Django
会将json
格式的数据存放进request.body
中。
import json
def test(request):
if request.method == "POST":
if request.is_ajax():
data = json.loads(request.body) // 直接反序列化
return JsonResponse("ok",safe=False)
return render(request,"base.html",locals())
发送文件
通过Ajax
发送发送文件,需要借助FormData
对象。
此外还要注意两点:
1.
contentType:false
// 不使用任何数据格式,任何编码2.
processData:false
// 不让浏览器做任何处理
<body>
<form action="">
<p><input type="text" name="username"></p>
<p><input type="text" name="password"></p>
<p><input type="file" name="userfile"></p>
<p><button type="button">提交</button></p>
</form>
</body>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<script>
window.onload = (() => {
document.querySelector("button").addEventListener("click", (ele) => {
let username = document.getElementsByName("username")[0].value;
let password = document.getElementsByName("password")[0].value;
// 获取文件对象
let userfile = document.getElementsByName("userfile")[0].files[0];
// FormData用于伪造form表单提交的数据
let FormDataObj = new FormData()
FormDataObj.append("username",username)
FormDataObj.append("password",password)
FormDataObj.append("userfile",userfile)
$.ajax({
url: "http://127.0.0.1:8000/",
type: "post",
dataType: 'JSON',
data:FormDataObj,
contentType:false, // 不做任何编码处理
processData:false, // 浏览器不要影响数据
success: (res) => {
console.log(res);
},
error:()=>{
console.log("失败");
}
})
})
})
</script>
def test(request):
if request.method == "POST":
msg = {
"username":request.POST.get("username"),
"password":request.POST.get("password"),
"userfile":request.FILES.get("userfile"),
}
print(msg)
# {'username': 'Yunya', 'password': '123', 'userfile': <InMemoryUploadedFile: django-orm单表练习.gif (image/gif)>}
return JsonResponse("ok",safe=False)
return render(request,"base.html",locals())
表单选项
如果要获取某个表单下的所有选项,则可使用以下的方法。
示例如下:
$.ajax({ data:$("#fm表单id").serialize(),
})
serialize()是获取表单下所有选项 这是jQuery提供的方法。
但是不会拿文件,当然也可以使用serializeArray(),它会将键值(文件除外)封装成数组套对象。
当有文件时,推荐使用serializeArry()再使用each循环添加至
FormData对象中。因为serialize()会将所有的键值对修改为url编码。
如:name=yunya&password=123
<body>
<form action="" id="f1">
<p><input type="text" name="username"></p>
<p><input type="text" name="password"></p>
<button type="button">提交</button>
</form>
</body>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<script>
window.onload = (() => {
document.querySelector("button").addEventListener("click", (ele) => {
$.ajax({
url: "http://127.0.0.1:8000/",
type: "post",
dataType: 'JSON',
data:$("#f1").serialize(),
success: (res) => {
console.log(res);
},
error:()=>{
console.log("失败");
}
})
})
})
</script>
def test(request):
if request.method == "POST":
print(request.POST)
# <QueryDict: {'username': ['Yunya'], 'password': ['123']}>
return JsonResponse("ok",safe=False)
return render(request,"base.html",locals())