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()
方式來判斷,前端是不是傳送的json
格式資料。
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").seriallze(), // 獲取表單下所有選項 這是jQuery提供的方法
})
<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())