Django中ajax的GET與POST請求、JavaScript與jQuery

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方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章