Ajax
Ajax 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML),是指?種創建互動式??應?的??開發技術,
Ajax 是?種?于創建快速動態??的技術,
Ajax 是?種在?需重新加載整個??的情況下,能夠更新部分??的技術,
通過在后臺與服務器進?少量資料交換,Ajax 可以使??實作異步更新,這意味著可以在不重新加載整個??的情況下,對??的某部分進?更新,
傳統的??(不使? Ajax)如果需要更新內容,必須多載整個????,
Ajax的優點:
異步:發送?個請求,不需要等待回應回傳,隨時可以再發送下?個請求,即不需要等待,
區域重繪:通過在后臺與服務器進行少量資料交換,Ajax 可以使網頁實作異步更新,這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新,【傳統的網頁(不使用 Ajax)如果需要更新內容,必須多載整個網頁頁面,】
應用場景:
這是一個cnblog賬戶注冊界面,當我們在填寫昵稱的時候輸入regina,這個程序本身并沒有進行表單提交或者向服務器發送請求,但是當游標離開這個input框之后,就會自動檢測了這里面的內容,并且回傳提示這個昵稱被占用了,而在圖二到圖三的程序當中,前端顯示為下圖,有一個重繪的程序,這個就是由于Ajax的區域重繪作用

這個程序中到底瀏覽器做了些什么作業

我們篩選出XHR(XmlHttpResponse)型別的報文,看到其實瀏覽器是進行了一個checkDisplayName的操作發送給了服務器,然后服務器的回傳如下


json回顧
映射關系
| Python | Json |
|---|---|
| dict | object |
| list, tuple | array |
| str | string |
| int, float | number |
| True | True |
| False | False |
| None | Null |
dic = {
'user':"regina",
'age':22,
'is_married':True
}
print(json.dumps(dic),type(json.dumps(dic)))
{"user": "regina", "age": 22, "is_married": true} <class 'str'>
可以看到字典中的單引號全部變成了雙引號,True映射成了true
dic = [{'user':"regina"},{'age':20}]
print(repr(json.dumps(dic)))
dic = ({'user':"regina"},{'age':20})
print(repr(json.dumps(dic)))
'[{"user": "regina"}, {"age": 20}]'
'[{"user": "regina"}, {"age": 20}]'
串列和元組全變為了陣列形式,
Ajax請求

首先確定一個概念就是Ajax請求不是表單提交,是JS代碼提交的,說明是要構建一個js代碼函式進行提交請求,所以這里的submit是沒有用的,現在構建一段js代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
<title>Title</title>
</head>
<body>
<h3>注冊界面</h3>
用戶名<input type="text" ><br>
密碼 <input type="password"><br>
<input type="submit">
<script>
$(".user").blur(function () {
alert(123);
})
</script>
</body>
</html>
首先做一個測驗,當游標移除用戶名時,會彈窗,

現在改為ajax請求的方式
<script>
$(".user").blur(function () {
$.ajax({
url:"http://127.0.0.1:8001/user/check/",
//請求方式默認get
})
})
</script>
然后我們設定好路由,在用戶名中輸入內容并離開框,看是否有新的請求發出,

我們的目的是要將input標簽里的用戶名傳給后端
$(".user").blur(function () {
$.ajax({
url:"http://127.0.0.1:8001/user/check/",
//請求方式默認get
data:{
"name" : $(".user").val()
},
})
})

經過測驗,我們的資料已經傳回給了后端,并且也可以列印出來,現在要做的就是進行一個驗證再反饋到前端
def check(request):
ret = User.objects.filter(username=request.GET.get("name"))
if ret:
return HttpResponse("用戶已存在")
else:
return HttpResponse("")


這樣的話請求我們就做好了
$.ajax({
url:"http://127.0.0.1:8001/user/check/",
//請求方式默認get
data:{
"name" : $(".user").val()
},
//當相回應正常時觸發當函式
success:function (res) {
console.log(res)
}
})

success引數得到了后端回應回來的資料,并列印了出來,現在可以通過dom物件的操作,將回傳內容添加到登陸界面進行提示,在用戶名標簽的后面添加一個span標簽,然后選中標簽進行添加內容
$(".err").html(res)


回應json資料
if ret:
res["exist"] = True
res["msg"] = "該用戶已存在"
return HttpResponse(json.dumps(res))
為什么要用序列化,首先json可以發送很多的介面資料,并且如果要自己一個一個引數傳會很麻煩,按照正常邏輯,上圖代碼中我們首先寫好了json.dumps 將序列化轉為字串,并且在html檔案中進行反序列化,
success:function (res) {
console.log(res);
data = https://www.cnblogs.com/ivanlee717/p/JSON.parse(res);
console.log(res);
if(data.exist){
$(".err").html(data.msg);
}
else{
$(".err").html(" ");
}
這樣我們也可以拿到序列化中的值,但是ajax好的一點就是當我們用JsonResponse(res),在html中我們可以直接呼叫引數,不需要再進行parse反序列化,

練習實體
用ajax實作一個加法
<input type="text" > + <input type="text" > = <input type="text" > <button >計算</button>
$(".btn").click(function () {
$.ajax({
url:"http://127.0.0.1:8001/user/add/",
type:"post",
data:{
"num1":$(".n1").val(),
"num2":$(".n2").val(),
},
success: function(res){
$(".ans").val(res);
}
})
})
def add(request):
num1 = int(request.POST.get("num1"))
num2 = int(request.POST.get("num2"))
return HttpResponse(str(num1+num2))

異步
同步請求指的是當我訪問url時,如果在視圖函式當中添加一個睡眠,讓服務器等待了5秒,
def reg(request):
time.sleep(5)
return render(request,"reg.html")

那么相應的,客戶端如圖所示,也需要等5秒才能進入頁面,
但是異步指的是當我在ajax請求的視圖函式當中添加一個睡眠,但其他的請求函式不做任何改變的話,那么這個睡眠等待只會影響這一個ajax請求,其他的正常作業,
def check(request):
ret = User.objects.filter(username=request.GET.get("name"))
res = {"exist":False, "msg":""}
time.sleep(5)
if ret:
res["exist"] = True
res["msg"] = "該用戶已存在"
return JsonResponse(res)
def add(request):
num1 = int(request.POST.get("num1"))
num2 = int(request.POST.get("num2"))
return HttpResponse(str(num1+num2))

同源策略

之前我們一直輸入的是ip地址和埠號以及路由,但是現在直接本地檔案的形式打開網頁,并且我們代碼的路由依然是服務器地址,但是依然會報錯,

但問題就是他這個路由請求沒有問題,我們可以在后端把1和2都列印出來,但是無法進行回應,


這是因為瀏覽器的同源策略導致的
同源策略概念
是一種約定,是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能都會被影響,可以說web是構建在同源策略之上的,瀏覽器只是針對同源策略的一種實作,
同源策略(same origin policy)是netScape(網景)提出的一個安全策略,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊,具體表現為瀏覽器在執行腳本前,會判斷腳本是否與打開的網頁是同源的,判斷協議、域名、埠是否都相同,相同則表示同源,其中一項不相同就表示跨域訪問,會在控制臺報一個CORS例外,目的是為了保護本地資料不被JavaScript代碼獲取回來的資料污染,因此攔截的是客戶端發出的請求回來的資料接收,即請求發送了,服務器回應了,但是無法被瀏覽器接收,

解決方案:跨域資源共享(CORS)
服務端設定,可以允許其他源訪問服務端資源,借助nodejs實作,
res = HttpResponse(str(num1+num2))
res["Access-Control-Allow-Origin"] = "*"
return res

headers里會有我們添加的那句話,識別到這句話就不會攔截了,
Cors有兩種請求,一種是簡單請求,一種是非簡單請求,只要滿足以下兩種要求之一就是簡單請求
(一)請求方法是下列三個之一:
GET
POST
HEAD
(二) HTTP的頭部資訊不超過以下幾種欄位:
- Accept
- Accept-language
- Content-language
- Last-Event-ID
- Content-Type:只限于三個值【application/x-www-form-urlencoded、multipart/form-data、text/plain】
本文來自博客園,作者:ivanlee717,轉載請注明原文鏈接:https://www.cnblogs.com/ivanlee717/p/16849676.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/524895.html
標籤:Python
