Django——Ajax相關
Ajax簡介
AJAX(Asynchronous Javascript And XML)翻譯成中文就是“異步Javascript和XML”。即使用Javascript語言與服務器進行異步交互,傳輸的數據為XML(當然,傳輸的數據不只是XML,現在更多使用json數據)。
- 同步交互:客戶端發出一個請求後,需要等待服務器響應結束後,才能發出第二個請求;
- 異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就可以發出第二個請求。
AJAX除了異步的特點外,還有一個就是:瀏覽器頁面局部刷新;(這一特點給用戶的感受是在不知不覺中完成請求和響應過程)
AJAX應用場景
-
索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字。
-
還有一個很重要的應用場景就是註冊時候的用戶名的查重。
-
其實這裏就使用了AJAX技術!當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,然後服務器會把查詢到的結果響應給瀏覽器,最後再把後端返回的結果展示出來。
-
整個過程中頁面沒有刷新,只是刷新頁面中的局部位置而已!
-
當請求發出後,瀏覽器還可以進行其他操作,無需等待服務器的響應!
-
整個過程中頁面沒有刷新,只是局部刷新了;
-
在請求發出後,瀏覽器不用等待服務器響應結果就可以進行其他操作;
AJAX的優缺點
優點:
- AJAX使用Javascript技術向服務器發送異步請求
- AJAX無須刷新整個頁面
- 因為服務器響應內容不再是整個頁面,而是頁面中的部分內容,所以AJAX性能高;
缺點:
- 每個點擊即請求一次,服務端的壓力會增大。
知識儲備:
需要的基礎知識
-
HTML / XHTML
-
CSS
-
JavaScript / DOM
什麽是JSON?
-
JSON 指的是 JavaScript 對象表示法(JavaScript Object Notation)
-
JSON 是輕量級的文本數據交換格式
-
JSON 獨立於語言 *
-
JSON 具有自我描述性,更易理解
* JSON 使用 JavaScript 語法來描述數據對象,但是 JSON 仍然獨立於語言和平臺。JSON 解析器和 JSON 庫支持許多不同的編程語言。
stringify與parse方法:
-
JavaScript中關於JSON對象和字符串轉換的兩個方法:
-
JSON.parse(): 用於將一個 JSON 字符串轉換為 JavaScript 對象
1 JSON.parse(‘{"name":"Q1mi"}‘); 2 JSON.parse(‘{name:"Q1mi"}‘) ; // 錯誤 3 JSON.parse(‘[18,undefined]‘) ; // 錯誤
JSON.stringify(): 用於將 JavaScript 值轉換為 JSON 字符串。
JSON.stringify({"name":"Q1mi"})
Django項目中如何使用json:
-
首先前端需要一個正確的序列化後的數據
-
註意:contentType:"application/json"一旦設定,data必須是json字符串,不能是json對象
- contentType:默認值:"application/x-www-form-urlencoded"。發送信息至服務器時內容編碼類型。用來指明當前請求的數據編碼格式;urlencoded:?a=1&b=2;如果想以其他方式提交數據,比如contentType:"application/json",即向服務器發送一個json字符串;
前端代碼:
$("#b1").click(function () { console.log(dict); json_obj = JSON.stringify({‘dict‘:dict, ‘data‘:$("#a1").attr("value")}); console.log(json_obj); $.ajax({ url: "/index/", type: "POST", data: json_obj, contentType:"application/json", success: function (data) { window.location.href = "/index/"; } }) })
- 後端解析數據
-
request_json = json.loads(request.body)
jQuery實現的AJAX:
AJXA語法
- 一般請求
$.ajax({ url: "/index/", #往哪發送請求 type:"POST", #請求的方法 data:{name:"dream",age:18}, #請求數據 success:function(data){ #請求被正常響應時,自動執行的回調函數,data為返回值 } })
- 提交攜帶文件類型的請求
var formData = new FormData(); #生成一個FormData var =fileobj = $("#f1")[0].files[0]#得到一個用戶選中的文件對象 formData.append("f1",fileobj) # 向formData對象中添加間值對數據 $.ajax({ url: "/index/", #往哪發送請求 type:"POST", #請求的方法 processData: false, #不讓jQuery處理我的數據 contentType: false, #不讓jQuery設置請求頭 data:formData, #請求數據 success:function(data){ #請求被正常響應時,自動執行的回調函數,data為返回值 } })
$.ajax參數
-
async
-
類型:Boolean
-
默認值: true。默認設置下,所有請求均為異步請求。如果需要發送同步請求,請將此選項設置為 false。
-
註意,同步請求將鎖住瀏覽器,用戶其它操作必須等待請求完成才可以執行。
-
-
data
-
類型:String
-
發送到服務器的數據。將自動轉換為請求字符串格式。GET 請求中將附加在 URL 後。查看 processData 選項說明以禁止此自動轉換。必須為 Key/Value 格式。如果為數組,jQuery 將自動為不同值對應同一個名稱。如 {foo:["bar1", "bar2"]} 轉換為 ‘&foo=bar1&foo=bar2‘。
-
-
type
-
類型:String默認值: "GET")。請求方式 ("POST" 或 "GET"),
-
默認為 "GET"。註意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。
-
-
url
-
類型:String
-
默認值: 當前頁地址。發送請求的地址。
-
-
processData
-
類型:Boolean
-
默認值: true。默認情況下,通過data選項傳遞進來的數據,如果是一個對象(技術上講只要不是字符串),都會處理轉化成一個查詢字符串,以配合默認內容類型 "application/x-www-form-urlencoded"。如果要發送 DOM 樹信息或其它不希望轉換的信息,請設置為 false。
- 註意:如果不需要jQuery去處理發送的數據是,請修改為false
-
-
contentType
-
類型:String
-
默認值: "application/x-www-form-urlencoded"。發送信息至服務器時內容編碼類型。默認值適合大多數情況。如果你明確地傳遞了一個 content-type 給 $.ajax() 那麽它必定會發送給服務器(即使沒有數據要發送)。
- 註意:如果需要jQuery不去設置Content-Type請求頭,則設置默認值為false。
-
-
success
-
類型:Function
-
請求成功後的回調函數。
-
參數:由服務器返回,並根據 dataType 參數進行處理後的數據;描述狀態的字符串。
-
這是一個 Ajax 事件。
-
jQuery實現AJAX上傳文件:
-
需要註意:不適用form表單提交數據時,需要在函數內使用 FormData() 方法生成一個表單對象
-
var formData = new FormData();
# 上傳文件 def upload(request): if request.method == ‘POST‘: file_obj = request.FILES.get(‘file‘,None) if file_obj: with open(file_obj.name,‘wb‘) as f: for chunk in file_obj.chunks(): f.write(chunk) return HttpResponse("上傳成功") return render(request,‘upload.html‘) return render(request,‘upload.html‘View Code
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>上傳文件</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> </head> <body> <input id="i1" type="file"> <button id="b1">點我</button> <script src="/static/jquery-3.3.1.min.js"></script> <script src="/static/setupAjax.js"></script> <script> $("#b1").click(function () { // 生成表單對象 var formData = new FormData(); formData.append("file",$("#i1")[0].files[0]); $.ajax({ url: "/upload/", type: "POST", // 告訴jQuery不要去處理發送的數據 processData: false, // 告訴jQuery不要去設置Content-Type請求頭 contentType: false, data: formData, success:function (data) { console.log(data) } }) }) </script> </body> </html>View Code
jQuery實現最基礎監控註冊用戶是否註冊
-
註意:盡量不要使用input事件,因為input事件是實時監聽,會給服務器造成壓力。
-
這裏選用的是,失去焦點事件,blur
前端代碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>註冊</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="/static/bootstrap-3.3.7/css/bootstrap.min.css"> <style> .error { color: red; } </style> </head> <body> <div> <label for="i1">用戶名</label> <input type="text" id="i1"> <span class="error" id="s1"></span> </div> <div> <label for="p1">密碼</label> <input type="password" id="p1"> </div> <div> <button id="b1">提交註冊</button> </div> <script src="/static/jquery-3.3.1.min.js"></script> <script> // 監控用戶名輸入框的焦點,只要i1失去焦點,就要把用戶填寫的往後臺發送 $("#i1").blur(function () { // 將s1的初始值設為空 $("#s1").text(""); // 獲取i1的值,即用戶輸入的值 var value = $(this).val(); // 調用ajax $.ajax({ // 提交到什麽地方 url: "/res2/", // 以什麽方式提交 type: "POST", // 傳送到後臺的數據 data: {name: value}, // 回調函數,data為返回值 success: function (data) { console.log(data); if (data.no_ok) { // 如果用戶已存在 $("#s1").text(data.msg) } } }) }) </script> </body> </html>View Code
後端代碼:
def res2(request): from django.http import JsonResponse res = {"no_ok": 0} if request.method == ‘POST‘: print(request.POST) user_name = request.POST.get(‘name‘) if user_name == ‘dream‘: res = {"no_ok": 1, "msg": "用戶已存在."} return JsonResponse(res) return render(request,‘res2.html‘)View Code
JS實現AJAX:
<script> let b1Ele = document.getElementById("b1"); b1Ele.onclick = function () { // 1. 生成xmlHttp對象 let xmlHttp = new XMLHttpRequest(); // 2. 調用xmlHttp的open方法設置請求相關配置項 xmlHttp.open("POST", "/ajax_js/", true); // 3. 設置請求頭 xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); // 4. 調用send方法發送數據 xmlHttp.send("username=dream&age=16"); // 5. 處理返回的響應 xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState === 4 && xmlHttp.status === 200) { alert(xmlHttp.responseText); } }; } </script>
AJAX請求如何設置csrf_token:
如果不設置csrf_token,則無法往後端發送數據,點擊查看詳細
方式一
通過獲取返回的cookie中的字符串,放在請求頭中發送。
註意:需要在html中引入jquery.cookie.js插件
- 導入<script src="/static/jquery.cookie.js"></script>
- 從Cookie取csrf_token,並設置ajax請求頭
<script> $("#b1").click(function () { var name = $("#i1").val(); var pwd = $("#p1").val(); $.ajax({ url: "/register/", type: "POST", headers: {"X-CSRFToken": $.cookie(‘csrftoken‘)}, // 從Cookie取csrf_token,並設置ajax請求頭 data: {name: name, pwd: pwd}, success:function (data) { if (!data.code){ // 登陸成功 location.href = data.data; } } }) }) </script>
方式二:
手動把csrf_token的值取到,塞進請求的data中
$("#b11").click(function () { // 點擊之後要做的事兒 $.ajax({ url: "/ajax_test2/", type: "POST", data: { i11: $("#i11").val(), i22: $("#i22").val(), // 取到csrf_token的值 csrfmiddlewaretoken: $("[name=‘csrfmiddlewaretoken‘]").val() }, success: function (data) { console.log(data); $("#i33").val(data); } }) });
方式三:
在一個單獨的JS文件中,給$.ajax統一設置一下請求頭
- 導入自己寫的js文件 setupAjax.js
文件代碼
復制保存到js文件中,導入到html中即可使用
/** * Created by oldboy on 2018/6/27. */ function getCookie(name) { var cookieValue = null; if (document.cookie && document.cookie !== ‘‘) { var cookies = document.cookie.split(‘;‘); for (var i = 0; i < cookies.length; i++) { var cookie = jQuery.trim(cookies[i]); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + ‘=‘)) { cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; } } } return cookieValue; } var csrftoken = getCookie(‘csrftoken‘); function csrfSafeMethod(method) { // these HTTP methods do not require CSRF protection return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method)); } $.ajaxSetup({ beforeSend: function (xhr, settings) { if (!csrfSafeMethod(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrftoken); } } });
註意事項:
- 如果發送的data中,數據不是簡單的字符串或數字,需要用JSON.stringify()轉換成JSON字符串
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>json提交數據</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> name<input type="text" id="n1"> password<input type="password" id="p1"> <button id="b1">提交</button> <script src="/static/jquery-3.3.1.min.js"></script> <script src="/static/setupAjax.js"></script> <script> $("#b1").click(function () { $.ajax( { url:"login", type:"POST", // 告訴遊覽器我發送的是一個json數據 contentType:"application/json", data:JSON.stringify({name:$("#n1").val(),pwd:$("#p1").val()}), success:function (data) { console.log(data) } } ) } ) </script> </body> </html>View Code
反序列化
import json json.loads(request.body)
在求頭中設置編碼格式:
- 常用的三種編碼格式
1 application/x-www-form-urlencoded 2 json 3 formdata
- 告訴遊覽器我使用的是json編碼格式
- 如果不設置則會采用默認的
Django——Ajax相關