一、Ajax介紹
Ajax(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據為XML(當然,傳輸的數據不只是XML)。
- 同步交互:客戶端發出一個請求后,需要等待服務器響應結束后,才能發出第二個請求;
- 異步交互:客戶端發出一個請求后,無需等待服務器響應結束,就可以發出第二個請求。
Ajax除了異步的特點外,還有一個就是:瀏覽器頁面局部刷新;(這一特點給用戶的感受是在不知不覺中完成請求和響應過程)。因此使用ajax的主要特點有如下幾點:(1)Ajax使用Javascript技術向服務器發送異步請求;(2)Ajax無須刷新整個頁面;(3)因為服務器響應內容不再是整個頁面,而是頁面中的局部,所以Ajax性能高。在django入門項目中我們已經簡單的介紹了一下ajax應用。下面我們將做詳細介紹。
二、ajax實現方式
具體實現方式實例如下:
html文件部分:
后端函數部分:
三、$.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 os
from 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")