Django——Ajax相關

 Ajax簡介

AJAX(Asynchronous Javascript And XML)翻譯成中文就是「異步Javascript和XML」。即便用Javascript語言與服務器進行異步交互,傳輸的數據爲XML(固然,傳輸的數據不僅是XML,如今更多使用json數據)。css

  • 同步交互:客戶端發出一個請求後,須要等待服務器響應結束後,才能發出第二個請求;
  • 異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就能夠發出第二個請求。
    AJAX除了異步的特色外,還有一個就是:瀏覽器頁面局部刷新;(這一特色給用戶的感覺是在不知不覺中完成請求和響應過程)

 

AJAX應用場景

  • 索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字。html

  • 還有一個很重要的應用場景就是註冊時候的用戶名的查重。前端

  • 其實這裏就使用了AJAX技術!當文件框發生了輸入變化時,使用AJAX技術向服務器發送一個請求,而後服務器會把查詢到的結果響應給瀏覽器,最後再把後端返回的結果展現出來jquery

    • 整個過程當中頁面沒有刷新,只是刷新頁面中的局部位置而已!ajax

    •  當請求發出後,瀏覽器還能夠進行其餘操做,無需等待服務器的響應!django

    • 整個過程當中頁面沒有刷新,只是局部刷新了;編程

    • 在請求發出後,瀏覽器不用等待服務器響應結果就能夠進行其餘操做;json

 

AJAX的優缺點

優勢:bootstrap

  • 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編碼格式

  

 

  • 若是不設置則會採用默認的

相關文章
相關標籤/搜索