ajax介紹
Ajax(Asynchronous Javascript And XML:異步 JavaScript 和 XML),是指一種在無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。
使用Ajax的最大優點,就是能在不更新整個頁面的前提下維護數據。這使得Web應用程序更爲迅捷地迴應用戶動作,並避免了在網絡上發送那些沒有改變的信息。
但是Ajax可能破壞瀏覽器的後退與加入收藏書籤功能。在動態更新頁面的情況下,用戶無法回到前一個頁面狀態,這是因爲瀏覽器僅能記下歷史記錄中的靜態頁面。
Ajax的定義
Ajax有最初是由js編寫的,後來隨着js框架的發展,jq,vue等大型框架都對ajax進行了封裝,在這裏我們學習兩種ajax的編寫。
Js ajax
我們看一個簡單的ajax案例
首先我們創建如圖所示的一個項目:
代碼如下:
# app01/views.py
from django.http import JsonResponse
from django.shortcuts import render
# Create your views here.
def getPage(request):
'''返回頁面'''
return render(request,'django_ajax_pro.html')
def sendData(request):
'''
響應ajax請求,在這裏要注意響應的內容是json對象
'''
return JsonResponse({"data":"hello world"})
#django_pro5/urls
from django.conf.urls import include, url
from django.contrib import admin
from app01.views import getPage, sendData
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^ckeditor/',include('ckeditor_uploader.urls')),
url(r'ajaxPro/',getPage),
url(r'ajaxData/',sendData),
]
<!--templates/django_ajax_pro.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ajax_js_example</title>
</head>
<body>
<button onclick="getData()">按我呀</button>
<script>
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //Msxml2版本Microsoft瀏覽器
}catch (e){
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");//Microsoft版本Microsoft瀏覽器
}catch (e1){
xmlhttp = new XMLHttpRequest();//非Microsoft瀏覽器,如:谷歌、Firefox等
}
}
function updatePage() {
console.log("+++++++++++++++++++++++++++++++++");
console.log(xmlhttp.readyState);
console.log(xmlhttp.status);
console.log("+++++++++++++++++++++++++++++++++");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var response = xmlhttp.responseText;//返回響應的內容
console.log(response)
}
}
function getData() {
url = "/ajaxData/";
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = updatePage;
xmlhttp.send(null)
}
console.log(xmlhttp)
</script>
</body>
</html>
效果如下:
在這裏我們關注上面的代碼的幾個點
1、在視圖當中我們定義了兩個函數,這裏大家一定要搞明白,ajax是局部提交,首先我們需要有頁面承載我們的前端效果,其次在前端發起ajax請求,進行響應的是一個獨立的視圖,並不是我們承載前端的視圖。
2、ajax通常返回的數據是json數據,在老版本的Django當中需要先導入json模塊,然後用HTTPRespose進行返回,在新版本django.http下已經封裝好了一個叫做JsonResponse的功能,他返回的就是json數據
3、js 編寫 ajax 的變化有很多種,但是一定注意他的必要的步驟,我們把剛纔的代碼拆開看一下
1. 構建XMLHttpRequest對象
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); //Msxml2版本Microsoft瀏覽器
}catch (e){
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");//Microsoft版本Microsoft瀏覽器
}catch (e1){
xmlhttp = new XMLHttpRequest();//非Microsoft瀏覽器,如:谷歌、Firefox等
}
}
2. 發起請求
function getData() {
url = "/ajaxData/";
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = updatePage;
xmlhttp.send(null)
}
3. 進行回調,響應函數
function updatePage() {
console.log("+++++++++++++++++++++++++++++++++");
console.log(xmlhttp.readyState);
console.log(xmlhttp.status);
console.log("+++++++++++++++++++++++++++++++++");
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var response = xmlhttp.responseText;//返回響應的內容
console.log(response)
}
}
在掌握了上面的例子之後,我們來解釋一些需要記住的常識
Ajax對象readyState的五種狀態
狀態編號 |
狀態 |
描述 |
0 |
未初始化 |
(XMLHttpRequest)對象已經創建,但還沒有調用open()方法。值爲0表示對象已經存在,否則瀏覽器會報錯:對象不存在。 |
1 |
載入/正在發送請求 |
對XMLHttpRequest對象進行初始化,即調用open()方法,根據參數(method,url,true),完成對象狀態的設置。並調用send()方法開始向服務端發送請求。值爲1表示正在向服務端發送請求。 |
2 |
載入完成/數據接收 |
此階段接收服務器端的響應數據。但獲得的還只是服務端響應的原始數據,並不能直接在客戶端使用。值爲2表示send()方法執行完成,已經接收完全部響應數據。併爲下一階段對數據解析作好準備。 |
3 |
交互/解析數據 |
此階段解析接收到的服務器端響應數據。即根據服務器端響應頭部返回的MIME類型把數據轉換成能通過responseBody、responseText或responseXML屬性存取的格式,爲在客戶端調用作好準備。值爲3表示正在解析數據。 |
4 |
後臺處理完成 |
此階段確認全部數據都已經解析爲客戶端可用的格式,解析已經完成。值爲4表示數據解析完畢,可以通過XMLHttpRequest對象的相應屬性取得數據。 |
Ajax對象status狀態碼(web request 請求響應碼)
200:請求成功(後臺處理結果ok) |
|
狀態碼 |
描述 |
200 |
服務器已成功處理了請求。通常,這表示服務器提供了請求的網頁。 |
201 |
請求成功且服務器已創建了新的資源。 |
202 |
服務器已接受了請求,但尚未對其進行處理。 |
203 |
服務器已成功處理了請求,但返回了可能來自另一來源的信息。 |
204 |
服務器成功處理了請求,但未返回任何內容。 |
205 |
服務器成功處理了請求,但未返回任何內容(與 204 響應不同,此響應要求請求者重置文檔視圖(例如清除表單內容以輸入新內容)。) |
206 |
服務器成功處理了部分 GET 請求。 |
303:重定向 |
|
狀態碼 |
描述 |
300 |
服務器根據請求可執行多種操作。 |
301 |
請求的網頁已被永久移動到新位置。服務器返回此響應時,會自動將請求者轉到新位置。 |
302 |
服務器目前正從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 |
303 |
當請求者應對不同的位置進行單獨的 GET 請求以檢索響應時,服務器會返回此代碼。 |
304 |
自從上次請求後,請求的網頁未被修改過。服務器返回此響應時,不會返回網頁內容。 |
305 |
請求者只能使用代理訪問請求的網頁。 |
307 |
服務器目前正從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。 |
400:請求錯誤 |
|
狀態碼 |
描述 |
400 |
服務器不理解請求的語法。 |
401 |
此頁要求授權。您可能不希望將此網頁納入索引。 |
403 |
服務器拒絕請求。 |
404 |
服務器找不到請求的網頁。例如,對於服務器上不存在的網頁經常會返回此代碼。 |
405 |
禁用請求中指定的方法。 |
406 |
無法使用請求的內容特性響應請求的網頁。 |
407 |
此狀態碼與 401 類似,但指定請求者必須授權使用代理。如果服務器返回此響應,還表示請求者應當使用代理。 |
408 |
服務器等候請求時發生超時。 |
409 |
服務器在完成請求時發生衝突。服務器必須在響應中包含有關衝突的信息。 |
410 |
請求的資源永久刪除後,服務器返回此響應。 |
411 |
服務器不接受不含有效內容長度標頭字段的請求。 |
412 |
服務器未滿足請求者在請求中設置的其中一個前提條件。 |
413 |
服務器無法處理請求,因爲請求實體過大,超出服務器的處理能力。 |
414 |
請求的 URI(通常爲網址)過長,服務器無法處理。 |
415 |
請求的格式不受請求頁面的支持。 |
416 |
如果頁面無法提供請求的範圍,則服務器會返回此狀態碼。 |
417 |
服務器未滿足"期望"請求標頭字段的要求。 |
500:服務器錯誤 |
|
狀態碼 |
描述 |
500 |
服務器遇到錯誤,無法完成請求。 |
501 |
服務器不具備完成請求的功能。 |
502 |
服務器作爲網關或代理,從上游服務器收到了無效的響應。 |
503 |
目前無法使用服務器(由於超載或進行停機維護)。通常,這只是一種暫時的狀態。 |
504 |
服務器作爲網關或代理,未及時從上游服務器接收請求。 |
505 |
服務器不支持請求中所使用的 HTTP 協議版本。 |
上面是js ajax get最簡單的案例,接下來看一個完整的js ajax的請求案例,我們以後端校驗用戶名是否重複爲例。
首先我們先定義一個列表作爲用戶池,用來存放已經存在的用戶名,當然,在工作當中我們是有數據庫存放用戶信息的。然後開始編寫接收數據之後進行比對的邏輯,返回的參數。
views視圖函數:
def userValidPage(request):
return render(request,'ajax_js_example.html')
def userValid(request):
'''響應ajax請求'''
userList = ["if","for","while","and","or","linux","python","django"]
result = {"state":"error","data":""}
if request.method == "GET" and request.GET:
request_name = request.GET.get("username")
if request_name:
if request_name in userList:
result["data"] = "用戶名已存在"
else:
result["state"] = "success"
result["data"] = "用戶名可以使用"
else:
result["data"] = "請輸入用戶名!"
else:
result["state"] = "error"
result["data"] = "我們只是接受get請求"
return JsonResponse(result)
url路由設置:
from django.conf.urls import include, url
from django.contrib import admin
from app01.views import getPage, sendData, userValidPage,userValid
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^ckeditor/',include('ckeditor_uploader.urls')),
url(r'ajaxPro/',getPage),
url(r'ajaxData/',sendData),
url(r'^ajax_page/',userValidPage),
url(r'^ajax_data/',userValid),
]
template前端頁面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input id="username" type="text"><!--用戶名稱文本框-->
<button id="submit" onclick="getData()">
提交註冊
</button><!--提交按鈕-->
<span id="errorMessage" style="color: red;"></span><!--提示文本-->
<script>
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e){
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e1){
xmlhttp = new XMLHttpRequest();
}
}
function updataPage() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200){
var response = xmlhttp.responseText;
var data = eval('('+response+')');
document.getElementById("errorMessage").innerHTML = data["data"];
console.log(data)
}
}
function getData() {
var name = document.getElementById("username").value;
if (name){
url = "/ajax_data/?username="+name;//get請求是可以拼接在url上以?開始鍵=值的形式
xmlhttp.open("GET",url,true);
xmlhttp.onreadystatechange = updataPage;
xmlhttp.send(null)
}else {
document.getElementById("errorMessage").innerHTML = "提交內容不可以爲空!"
}
}
</script>
</body>
</html>
在這裏有個問題大家要注意。Js ajax返回的數據是一個字符串,我們需要將他強行轉換爲json格式,所以使用evel方法進行了轉換
var response = xmlhttp.responseText;
var data = eval('('+response+')');
這樣寫的原因在於:eval本身的問題。 由於json是以”{}”的方式來開始以及結束的,在JS中,它會被當成一個語句塊來處理,所以必須強制性的將它轉換成一種表達式。
加上圓括號的目的是迫使eval函數在處理JavaScript代碼的時候強制將括號內的表達式(expression)轉化爲對象,而不是作爲語句(statement)來執行。舉一個例子,例如對象子變量{},如若不加外層的括號,那麼eval會將大括號識別爲JavaScript代碼塊的開始和結束標記,那麼{}將會被認爲是執行了一句空語句。所以下面兩個執行結果是不同的:
alert(eval("{}"); // return undefined
alert(eval("({})");// return object[Object]
我們執行的效果如下:
Jq ajax
上面我們講了js的ajax請求,下面來看一下jq的ajax 請求。相對於js的ajax get請求,jq的編寫更加簡單。
還是上面的例子,我們用jq實現一下,後端ajax數據校驗視圖代碼我們不用動。
views視圖增加一個承載頁面:
def jqValidPage(request):
return render(request,'ajax_jq_example.html')
然後將jq文件方法static目錄,(當然在這裏是要配置Django的靜態目錄的)
Settings靜態目錄配置
STATICFILES_DIRS = (
os.path.join(BASE_DIR,"static"),
)
路由指出也不要忘了
from django.conf.urls import include, url
from django.contrib import admin
from app01.views import getPage, sendData, userValidPage,userValid,jqValidPage
urlpatterns = [
url(r'^ajax_jq_page',jqValidPage),
]
接下來我們來編寫前端的jq請求:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="/static/jq/jquery-3.1.1.min.js"></script><!--導入外部的jq文件-->
</head>
<body>
<input id = "username" type = "text"><!--用戶名稱文本框-->
<button id = "submit" onclick = "getData()">
提交
</button><!--提交按鈕-->
<span id = "errorMessage" style = "color: red;"></span> <!--提示文本-->
<script>
function getData() {
var name = $("#username").val();
console.log(name);
if (name){
$.ajax(
{
url:"/ajax_data/?username="+name,
type:"get",
data:"",
success:function (data) {
console.log(data);
$("errorMessage").text(data["data"])
},
error:function (error) {
console.log(error)
}
}
)
}else {
$("errorMessage").text("提交內容不可以爲空")
}
}
</script>
</body>
</html>
效果如下:
從上面的方法看出,在實現相同功能的情況下,jQuery的代碼要JavaScript的代碼簡潔很多
Ajax常用的配置參數給大家展示一下
參數名稱 |
參數類型 |
參數描述 |
async |
Boolean |
默認設置下,所有請求均爲異步請求。如果需要發送同步請求,請將此選項設置爲 false。 |
beforeSend |
Function |
發送請求前可修改 XMLHttpRequest 對象的函數,如添加自定義 HTTP 頭。 |
cache |
Boolean |
true,dataType 爲 script 和 jsonp 時默認爲 false。設置爲 false 將不緩存此頁面。 |
contentType |
String |
"application/x-www-form-urlencoded"。發送信息至服務器時內容編碼類型。 |
context |
Object |
這個對象用於設置 Ajax 相關回調函數的上下文。也就是說,讓回調函數內 this 指向這個對象(如果不設定這個參數,那麼 this 就指向調用本次 AJAX 請求時傳遞的 options 參數)。比如指定一個 DOM 元素作爲 context 參數,這樣就設置了 success 回調函數的上下文爲這個 DOM 元素。 |
data |
String |
發送到服務器的數據。將自動轉換爲請求字符串格式。GET 請求中將附加在 URL 後。查看 processData 選項說明以禁止此自動轉換。必須爲 Key/Value 格式。如果爲數組,jQuery 將自動爲不同值對應同一個名稱。如 {foo:["bar1", "bar2"]} 轉換爲 '&foo=bar1&foo=bar2'。 |
dataFilter |
Function |
給 Ajax 返回的原始數據的進行預處理的函數。提供 data 和 type 兩個參數:data 是 Ajax 返回的原始數據,type 是調用 jQuery.ajax 時提供的 dataType 參數。函數返回的值將由 jQuery 進一步處理。 |
dataType |
String |
預期服務器返回的數據類型。如果不指定,jQuery 將自動根據 HTTP 包 MIME 信息來智能判斷,比如 XML MIME 類型就被識別爲 XML。在 1.4 中,JSON 就會生成一個 JavaScript 對象,而 script 則會執行這個腳本。隨後服務器端返回的數據會根據這個值解析後,傳遞給回調函數。 |
error |
Function |
自動判斷 (xml 或 html)。 |
global |
Boolean |
是否觸發全局 AJAX 事件。 |
ifModified |
Boolean |
僅在服務器數據改變時獲取新數據。 |
jsonp |
String |
在一個 jsonp 請求中重寫回調函數的名字。 |
jsonpCallback |
String |
爲 jsonp 請求指定一個回調函數名。 |
password |
String |
用於響應 HTTP 訪問認證請求的密碼 |
success |
Function |
請求成功後的回調函數。 |
timeout |
Number |
設置請求超時時間(毫秒)。此設置將覆蓋全局設置。 |
type |
String |
默認值: "GET")。請求方式 ("POST" 或 "GET"), 默認爲 "GET"。 |
url |
String |
默認當前頁地址。發送請求的地址。 |
以上就是ajax的GET方法下的js以及jq,後期我會再給大家帶來ajax的POST方法