django中ajax介紹及應用
django中ajax應用
一、Ajax介紹
Ajax(Asynchronous Javascript And XML)翻譯成中文就是“非同步Javascript和XML”。即使用Javascript語言與伺服器進行非同步互動,傳輸的資料為XML(當然,傳輸的資料不只是XML)。
- 同步互動:客戶端發出一個請求後,需要等待伺服器響應結束後,才能發出第二個請求;
- 非同步互動:客戶端發出一個請求後,無需等待伺服器響應結束,就可以發出第二個請求。
Ajax除了非同步的特點外,還有一個就是:瀏覽器頁面區域性重新整理;(這一特點給使用者的感受是在不知不覺中完成請求和響應過程)。因此使用ajax的主要特點有如下幾點:(1)Ajax使用Javascript技術向伺服器傳送非同步請求;(2)Ajax無須重新整理整個頁面;(3)因為伺服器響應內容不再是整個頁面,而是頁面中的區域性,所以Ajax效能高。在django入門專案中我們已經簡單的介紹了一下ajax應用。下面我們將做詳細介紹。
二、ajax實現方式
具體實現方式例項如下:
html檔案部分: object是js中的物件,可以理解類似於python中的字典。
後端函式部分:
三、$.Ajax的引數
1、contentType型別一
上述例項中是我們對ajax的基本使用,也是ajax中引數contentType的預設使用方式,他決定了傳送資訊至伺服器時內容編碼的型別。現將此引數的預設使用方式總結如下:
data: 當前ajax請求要攜帶的資料,是一個object物件,ajax方法就會預設地把它編碼成某種格式(urlencoded:?a=1&b=2)傳送給服務端;此外,ajax預設以get方式傳送請求。 contentType:"application/x-www-form-urlencoded"。傳送資訊至伺服器時內容編碼型別。用來指明當前請求的資料編碼格式;urlencoded:?a=1&b=2;
2、contentType型別二
上述這種預設引數形式,data中的csrf跨站請求偽造鍵值對會被中介軟體自動識別,contentType引數還有如下一種形式,介紹如下:
contentType:"application/json",即向伺服器傳送一個json字串。注意:contentType:"application/json"一旦設定,data必須是json字串,不能是json物件
html檔案部分:
後端函式部分:
上述通過headers引數傳送csrf跨站請求偽造其實共有兩種方式獲取那個值,分別總結如下:
方式一: headers:{"X-CSRFToken":$("[name='csrfmiddlewaretoken']").val()} 方式二: headers:{"X-CSRFToken":$.cookie("csrftoken")}, #其中方式二需引用jquery.cookie.js檔案,如:<script src="https://cdn.bootcss.com/jquery-cookie/1.4.1/jquery.cookie.js"></script>
四、上傳檔案
1、form表單上傳
如下例項以註冊頁面為例,form表單提交的時候需要在form中設定enctype="multipart/form-data"屬性,使得form中資料和file檔案以不同的方式傳送值後端,後端通過不同的方法取出相應的資料進行處理。
html檔案:
<form class="form-horizontal" style="margin-top: 20px" action="{{ request.get_full_path }}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="col-sm-offset-4 col-sm-8">
<h2>註冊頁面</h2>
<span style="color: red"> {{ error_msg }}</span>
</div>
<div class="form-group">
<label for="username" class="col-sm-2 control-label col-sm-offset-2">姓名</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="username" placeholder="數字或字母組成,不能包含特殊字元" name="username">
</div>
</div>
<div class="form-group">
<label for="userpswd1" class="col-sm-2 control-label col-sm-offset-2">密碼</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="userpswd1" placeholder="密碼長度至少為8位字元組成" name="userpswd1">
</div>
</div>
<div class="form-group">
<label for="userpswd2" class="col-sm-2 control-label col-sm-offset-2">確認密碼</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="userpswd1" placeholder="密碼長度至少為8位字元組成" name="userpswd2">
</div>
</div>
<div class="form-group">
<label for="img_file" class="col-sm-2 control-label col-sm-offset-2">上傳頭像</label>
<div class="col-sm-4">
<input type="file" id="img_file" name="img_file">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<input type="submit" class="btn btn-success btn-lg btn-block" value="確定">
</div>
</div>
</form>
後端處理函式:
import osfrom day78.settings import BASE_DIR
def formreg(request):
if request.method=="POST":
print(request.POST)
user=request.POST.get("username")
userpswd1=request.POST.get("userpswd1")
userpswd2=request.POST.get("userpswd2")
print(user,userpswd1,userpswd2)
if userpswd1==userpswd2:
User.objects.create_user(username=user,password=userpswd1)
print(request.FILES)
file_obj=request.FILES.get("img_file") #獲取檔案物件
file_name=file_obj.name #獲取檔名字
path = os.path.join(BASE_DIR, "app01", "static", file_name)
with open(path,"wb") as f:
for line in file_obj:
f.write(line)
return HttpResponse("註冊成功")
return render(request,"formreg.html")
2、ajax上傳檔案
html檔案部分:
<form class="form-horizontal" style="margin-top: 20px">
{% csrf_token %}
<div class="col-sm-offset-4 col-sm-8">
<h2>註冊頁面</h2>
<span style="color: red" class="error_msg"></span>
</div>
<div class="form-group">
<label for="username" class="col-sm-2 control-label col-sm-offset-2">姓名</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="username" placeholder="數字或字母組成,不能包含特殊字元" name="username">
</div>
</div>
<div class="form-group">
<label for="userpswd1" class="col-sm-2 control-label col-sm-offset-2">密碼</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="userpswd1" placeholder="密碼長度至少為8位字元組成" name="userpswd1">
</div>
</div>
<div class="form-group">
<label for="userpswd2" class="col-sm-2 control-label col-sm-offset-2">確認密碼</label>
<div class="col-sm-4">
<input type="password" class="form-control" id="userpswd2" placeholder="密碼長度至少為8位字元組成" name="userpswd2">
</div>
</div>
<div class="form-group">
<label for="img_file" class="col-sm-2 control-label col-sm-offset-2">上傳頭像</label>
<div class="col-sm-4">
<input type="file" id="img_file" name="img_file">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-4">
<input type="button" class="btn btn-success btn-lg btn-block" value="確定" id="ensure">
</div>
</div>
</form>
<div style="margin-left: 220px">
<img src="/static/3.jpg" alt="" class="img-rounded">
<img src="/static/3.jpg" alt="" class="img-circle">
<img src="/static/3.jpg" alt="" class="img-thumbnail">
</div>
</div>
<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script>
$("#ensure").click(function () {
var $formData=new FormData();
$formData.append("username",$("#username").val());
$formData.append("userpswd1",$("#userpswd1").val());
$formData.append("userpswd2",$("#userpswd2").val());
$formData.append("img_file",$("#img_file")[0].files[0]);
$.ajax({
url:"/ajaxreg/",
type:"POST",
data:$formData,
contentType:false,
processData:false,
headers:{"X-CSRFToken":$('[name="csrfmiddlewaretoken"]').val()},
success:function (data) {
$(".error_msg").text(data)
}
})
})
</script>
後端處理函式:
與form提交處理的方式一樣,如下:
import os
from day78.settings import BASE_DIR
def ajaxreg(request):
if request.is_ajax():
username = request.POST.get("username")
userpswd1 = request.POST.get("userpswd1")
userpswd2 = request.POST.get("userpswd2")
print(username, userpswd1, userpswd2)
if userpswd1 == userpswd2:
User.objects.create_user(username=username, password=userpswd1)
print(request.FILES)
file_obj = request.FILES.get("img_file") # 獲取檔案物件
file_name = file_obj.name # 獲取檔名字
path = os.path.join(BASE_DIR, "app01", "static", file_name)
with open(path, "wb") as f:
for line in file_obj:
f.write(line)
return HttpResponse("註冊成功")
else:
return HttpResponse("註冊失敗")
return render(request,"ajaxreg.html")