jQuery Ajax

雲崖先生 發表於 2020-09-15

Ajax介紹

   Ajax能夠在不重新整理頁面的情況下傳送並接受後端資料。

   是現在Web開發中大量使用的一種技術。

   這裡介紹一下jQuery中的Ajax

資料格式

   在前後端互動中,總共有三種格式。不同的格式對應後端不同的框架中有不同的處理方式,這裡以Django為例。

   如果要檢視你傳送資料的格式,可在請求頭中有一個Content-Type中進行檢視。

urlencoded

   urlencoded是預設的編碼格式,不論是使用form表單,或者是ajax

   當你使用此種編碼格式時,將不能上傳檔案,並且資料格式為username=xxx&password=xxx

   在Django中,會將此種編碼格式存放至響應的請求方式中,如request.GET/request.POST

multipart/form-data

   multipart/form-data允許上傳檔案,在Django中將會把檔案放在request.FILES中,而其他資料則會放在request.POST中。

   注意:multipart/form-data只能由POST進行上傳。

application/json

   json格式常見於ajax傳送請求中,特別是前後端分離專案。這種格式非常常見,而後端如果是使用Django,那麼Django會將資料儲存在request.body中。

   並且我們可以在檢視函式中使用request.is_ajax()方式來判斷,前端是不是傳送的json格式資料。

import json

if request.is_ajax():
	data = request.body
	json.loads(data)

基本使用

   jQuery中封裝的Ajax使用十分便捷,以下操作將演示如何傳送Ajax請求並且讓後端返回相應的資料。

   注意事項

   1.前端傳遞引數中,不允許出現物件巢狀的形式。如{"k1":{"k1-1":v1}}

   2.如果前端傳遞的是一個Array,如{"k1":[1,2,3,4]}則需要新增一個屬性traditional:true,否則後端將接收不到該引數。(實際上接受的時候要使用request.POST.get("k1[]"))來進行接受,這是有問題的。

   <QueryDict: {'k1[]': ['1', '2', '3', '4']}>

$.ajax({
    url: "http://127.0.0.1:8000/",  // 傳送的路徑
    type: "post",  // 傳送方式
    dataType: 'JSON',  // 反序列化
    data:{v1,v2},  // 傳送的資料
    success: (res) => {  // 成功獲取到後端返回結果的回撥函式
    	res_ele.value = res;
    },
    error:()=>{  // 傳送失敗的回撥函式
    	console.log("失敗");
    }
})
<body>
    <p><input type="text"></p>
    <p><input type="text"></p>
    <p><input type="text" readonly style="background-color: #eee;"></p>
    <p><button type="button">提交</button></p>
</body>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<script>
    window.onload = (() => {

        document.querySelector("button").addEventListener("click", (ele) => {
            let v1 = document.querySelectorAll("input")[0].value;
            let v2 = document.querySelectorAll("input")[1].value;
            let res_ele = document.querySelectorAll("input")[2];

            $.ajax({
            
                url: "http://127.0.0.1:8000/",  // 傳送的路徑
                type: "post",  // 傳送方式
                dataType: 'JSON',  // 反序列化
                data:{v1,v2},  // 傳送的資料
                success: (res) => {  // 成功獲取到後端返回結果的回撥函式
                    res_ele.value = res;
                },
                error:()=>{  // 傳送失敗的回撥函式
                    console.log("失敗");
                }
            })

        })


    })

</script>
def test(request):
    if request.method == "POST":
        v1 = request.POST.get("v1")
        v2 = request.POST.get("v2")
        res = int(v1) + int(v2)
        return JsonResponse(res,safe=False)
    return render(request,"base.html",locals())

傳送Json

   如果前端要傳送JSON格式的資料,則需要宣告資料格式為JSON

  

$.ajax({
    url: "http://127.0.0.1:8000/", // 傳送的路徑
    type: "post", // 傳送方式
    dataType: 'JSON', // 反序列化
    data:JSON.stringify({"name":"Yunya","age":18}),   // 傳送的資料,注意,這裡一定要序列化,因為已經宣告瞭。
    contentType:'application/json',  // 宣告傳送資料格式
    success: (res) => {
        console.log(res);
    },
    error:()=>{
        console.log("失敗");
    }
})

   注意:Django會將json格式的資料存放進request.body中。

import json

def test(request):
    if request.method == "POST":
        if request.is_ajax():
            data = json.loads(request.body) // 直接反序列化
            return JsonResponse("ok",safe=False)

    return render(request,"base.html",locals())

傳送檔案

   通過Ajax傳送傳送檔案,需要藉助FormData物件。

   此外還要注意兩點:

   1.contentType:false // 不使用任何資料格式,任何編碼

   2.processData:false // 不讓瀏覽器做任何處理

<body>
    <form action="">
        <p><input type="text" name="username"></p>
        <p><input type="text" name="password"></p>
        <p><input type="file" name="userfile"></p>
        <p><button type="button">提交</button></p>

    </form>
</body>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<script>
    window.onload = (() => {

        document.querySelector("button").addEventListener("click", (ele) => {

            let username = document.getElementsByName("username")[0].value;

            let password = document.getElementsByName("password")[0].value;

            // 獲取檔案物件
            let userfile = document.getElementsByName("userfile")[0].files[0];

            // FormData用於偽造form表單提交的資料
            let FormDataObj = new FormData()

            FormDataObj.append("username",username) 
            FormDataObj.append("password",password)
            FormDataObj.append("userfile",userfile)
            

            $.ajax({

                url: "http://127.0.0.1:8000/",
                type: "post",
                dataType: 'JSON',

                data:FormDataObj,
                contentType:false,  // 不做任何編碼處理
                processData:false,   // 瀏覽器不要影響資料

                success: (res) => {
                    console.log(res);

                },
                error:()=>{
                    console.log("失敗");
                }
            })

        })

    })

</script>
def test(request):
    if request.method == "POST":
        msg = {
            "username":request.POST.get("username"),
            "password":request.POST.get("password"),
            "userfile":request.FILES.get("userfile"),
        }
        print(msg)
        # {'username': 'Yunya', 'password': '123', 'userfile': <InMemoryUploadedFile: django-orm單表練習.gif (image/gif)>}

        return JsonResponse("ok",safe=False)

    return render(request,"base.html",locals())

表單選項

   如果要獲取某個表單下的所有選項,則可使用以下的方法。

   示例如下:

$.ajax({
	data:$("#fm表單id").seriallze(),  // 獲取表單下所有選項 這是jQuery提供的方法
})
<body>
    <form action="" id="f1">
        <p><input type="text" name="username"></p>
        <p><input type="text" name="password"></p>
        <button type="button">提交</button>
    </form>
</body>
<script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js'></script>
<script>
    window.onload = (() => {
        document.querySelector("button").addEventListener("click", (ele) => {
            $.ajax({
                url: "http://127.0.0.1:8000/",
                type: "post",
                dataType: 'JSON',
                data:$("#f1").serialize(),
                success: (res) => {
                    console.log(res);

                },
                error:()=>{
                    console.log("失敗");
                }
            })
        })
    })
</script>
def test(request):
    if request.method == "POST":
        print(request.POST)
                
        # <QueryDict: {'username': ['Yunya'], 'password': ['123']}> 
        return JsonResponse("ok",safe=False)

    return render(request,"base.html",locals())