Ajax
Ajax簡介
AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步的Javascript和XML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(當然,傳輸的數據不只是XML)。
AJAX 不是新的編程語言,而是一種使用現有標準的新方法。
AJAX 最大的優點是在不重新加載整個頁面的情況下,可以與服務器交換數據並更新部分網頁內容。(這一特點給用戶的感受是在不知不覺中完成請求和響應過程)
AJAX 不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執行。
- 同步交互:客戶端發出一個請求後,需要等待服務器響應結束後,才能發出第二個請求;
- 異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就可以發出第二個請求。
Ajax常見應用情景
搜索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字。
還有一個很重要的應用場景就是註冊時候的用戶名的查重。
其實這裏就使用了AJAX技術!當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,然後服務器會把查詢到的結果響應給瀏覽器,最後再把後端返回的結果展示出來。
- 整個過程中頁面沒有刷新,只是刷新頁面中的局部位置而已!
- 當請求發出後,瀏覽器還可以進行其他操作,無需等待服務器的響應!
Ajax優點
- AJAX使用JavaScript技術向服務器發送異步請求;
- AJAX請求無須刷新整個頁面;
- 因爲服務器響應內容不再是整個頁面,而是頁面中的部分內容,所以AJAX性能高;
總結: 1.局部刷新,2.異步請求
Ajax使用
/*基本參數:*/
1.url : 提交的地址
2.type : 提交的方式(默認GET)
3.data : 提交的數據
4.dataType:'JSON' 會自動將Django以HttpResponse響應的數據反系列化(該參數可以指定)
return HttpResponse(json.dumps(back_dic)) # 需要dataType參數
return JsonResponse(back_dic) # 不需要
5.success : 回調函數(因爲是異步提交,需要回調函數,取結果)
/*基本語法:*/ Ajax通常與事件綁定使用
$('#d1').click(function() {
$.ajax({
url:'/index/', // 提交的地址
type:'post', // 提交的方式
data:{'name':'xionger', 'password':'123'} // 提交的數據
success:function(data) {
alert(data) // data接收的就是異步提交返回的結果
}
})
})
注意: data參數中的鍵值對,如果值值不爲字符串,需要將其轉換成字符串類型。
案例:
求和案例
<!--前端-->
<body>
<input type="text" id="id1"> + <input type="text" id="id2"> = <input type="text" id="id3">
<button id="b1">求和</button>
<script>
$('#b1').click(function () {
$.ajax({
url:'',
type:'post',
data:{'id1':$('#id1').val(),'id2':$('#id2').val()},
success:function (data) {
// {alert(data)} data形參用來接收異步提交的結果
$('#id3').val(data) // 通過DOM操作,將結果渲染到第三個input框中
}
})
})
</script>
</body>
# 後端
def index(request):
if request.is_ajax(): # 判斷是否是Ajax
if request.method == 'POST': # POST 方式請求的數據都在POST中
id1 = request.POST.get('id1')
id2 = request.POST.get('id2')
# 數據傳輸過來d都是字符串,強轉整型
id1 = int(id1)
id2 = int(id2)
res = id1 + id2
# 將結果返回到前端
return HttpResponse(res)
return render(request, 'index.html')
contentType
前後端傳輸數據編碼格式
1.urlencoded # form表單與Ajax默認的數據編碼格式
2.formdata # form表單
3. json # Ajax
ps: Ajax傳輸文件建議使用內置對象: new Formdata()
'''注意:前後端傳輸數據的時候,一定要保證數據格式和你的編碼格式是一致的'''
urlencoded
1.數據格式: name=xionger&password=123
2.Django後端針對urlencoded編碼格式的數據會自動解析並放到 request.POST 中.
3.form表單與Ajax默認的數據編碼格式
formdata
1.form表單傳輸文件的編碼格式
2.Django後端針對form表單指定formdata格式傳輸文件就會自動解析並將文件放到request.FILES中
3.使用:<form action="" method="post" enctype="multipart/form-data">
json
1.Ajax發送json格式數據
2.Django後端針對json格式的數據,並不會自動解析放到request.POST或者request.FILES裏面,
它並不會解析json格式數據,而是將它原封不動的放在request.body中
3.使用:
data:JSOM.stringify({'name':'xionger', 'password':123})
ps:JSOM.stringify() 類似 json.dumps()
問題: django後端針對不同的編碼格式是如何處理的?
- 1.只要是符合urlencoded編碼格式 都會被後端自動獲取並解析放到request.POST中
- 2.如果是符合formdata那麼文件會自動被解析放到request.FILES中
- 3.如果是json格式 後端默認不解析 以二進制的形式就放在request.body你可以自己手動處理即可
案例:
Ajax發送json格式數據
<!--前端-->
<body>
<input type="text" id="name" > <input type="text" id="pwd" >
<button id="b1">登錄</button>
<script>
$('#b1').click(function () {
$.ajax({
url:'',
type:'post',
data:JSON.stringify({'id1':$('#name').val(),'id2':$('#pwd').val()}),
contentType:'application/json', // 告訴後端傳世的數據時json格式
success:function (data) {
{alert(data)} // data形參用來接收異步提交的結果
$('#id3').val(data) // 通過DOM操作,將結果渲染到第三個input框中
}
})
})
</script>
</body>
# 後端
import json
def login(request):
if request.is_ajax(): # 判斷是否是Ajax
if request.method == 'POST':
json_bytes = request.body # 前端json格式傳輸的數據都在request.body中
# 在request.body中,json格式的數據沒有任何處理,是二進制形式,需要後端反序列化
print(json.loads(json_bytes)) # {'id1': 'xionger', 'id2': '123'}
name = json.loads(json_bytes).get('name')
password = json.loads(json_bytes).get('pwd')
print(name) # xionger
print(password) # 123
# 將結果返回到前端
return HttpResponse('OK')
return render(request, 'ajax_json.html')
serializers
當拿到由ORM得到的數據庫裏面的一個個用戶對象,後端想直接將實例化出來的數據對象直接發送給客戶端,那麼這個時候,就可以用Django給我們提供的序列化方式
# 後端:
def ser(request):
#拿到用戶表裏面的所有的用戶對象
user_list=models.User.objects.all()
#導入內置序列化模塊
from django.core import serializers
#調用該模塊下的方法,第一個參數是你想以什麼樣的方式序列化你的數據
ret=serializers.serialize('json',user_list)
return render(request,'index.html',locals())
# 前端得到:
[{"model": "app01.user","pk": 1,"fields":
{"username": "jason","age": 18,"gender": 1}
}......]
分頁器
# 前端
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
{% for book in page_queryset %}
<p>{{ book.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}
</div>
</div>
</div>
</body>
# 後端
from app01.utils.mypage import Pagination
def book(request):
book_list = models.Book.objects.all()
current_page = request.GET.get("page",1)
all_count = book_list.count()
page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
page_queryset = book_list[page_obj.start:page_obj.end]
return render(request,'booklist.html',locals())
# current_page: 當前頁
# all_count: 數據庫中的數據總條數
# per_page_num: 每頁顯示的數據條數
# pager_count: 最多顯示的頁碼個數