1. 程式人生 > >AJAX請求提交數據

AJAX請求提交數據

進制 最大的 version token getname 等待 簡單 性能 t對象

1,AJAX準備知識:JSON

JSON指的是JavaScript對象表示方法(JavaScript Object Notation)

JSON是輕量級的文本數據交換格式

JSON獨立於語言

JSON具有自我描述性, 更易理解

JSON使用JavaScript語法來描述數據對象,但是JSon仍然獨立於語言和平臺,json解析器和json庫支持許多不同的語言

技術分享圖片

合格的json對象:

["雪雪","小雪","雪兒","小雪砸","雪人"]
{"雪雪":1,"小雪":2,"雪人":3,"雪兒":4,"小雪砸":5}
{"name":["雪雪","小雪"]}
{{"name":"雪雪","name":"小雪"}}

不合格的json對象:

{name:"雪雪","age":29}  # 屬性名必須使用雙引號
[29,26,28,0xFFF]  # 不能使用十六進制
{"name":"雪雪","name":undefined}  # 不能使用undefined
{"name":"雪雪",
"birthday":new Date(日期),
"getName": function(){return this name;}  # 不能使用日期和函數對象
}        

2,stringify和parse方法

JavaScript中關於JSON對象和字符串轉換的兩個方法:

JSON.parse():將用於一個JSON字符串轉化為JavaScript對象

JSON.parse("{"name":"雪雪"}");
JSON.parse("{name:"雪雪"}");  // 錯誤
JSON.parse("{29,undefined}");  // 錯誤

JSON.stringfy():用於將JavaScript值轉化為JSON字符串

JSON.stringfy({"name":"雪雪"})

3,和XML比較

JSON格式於2001年由Douglas Crockford提出,目的就是取代繁瑣笨重的XML格式.

JSON格式有兩個顯著的優點:書寫簡單,一目了然;符合JavaScript原生語法,可以由解釋引擎 直接處理,不用添加解析代碼,所以,JSON迅速被接受,已經成為各大網站交換的標準的格式,並被寫入ECMAScript5,成為標準的一部分

XML和JSON都使用結構化時間來標記數據,下面來做一個簡單的比較

用XML表示額數據如下:

技術分享圖片技術分享圖片
<?xml version="1.0" encoding="utf-8"?>
<country>
    <name>中國</name>
    <province>
        <name>黑龍江</name>
        <cities>
            <city>哈爾濱</city>
            <city>大慶</city>
        </cities>
    </province>
    <province>
        <name>廣東</name>
        <cities>
            <city>廣州</city>
            <city>深圳</city>
            <city>珠海</city>
        </cities>
    </province>
    <province>
        <name>臺灣</name>
        <cities>
            <city>臺北</city>
            <city>高雄</city>
        </cities>
    </province>
    <province>
        <name>新疆</name>
        <cities>
            <city>烏魯木齊</city>
        </cities>
    </province>
</country>
XML表示中國的省份

用JSON表示如下:

技術分享圖片技術分享圖片
{
    "name": "中國",
    "province": [{
        "name": "黑龍江",
        "cities": {
            "city": ["哈爾濱", "大慶"]
        }
    }, {
        "name": "廣東",
        "cities": {
            "city": ["廣州", "深圳", "珠海"]
        }
    }, {
        "name": "臺灣",
        "cities": {
            "city": ["臺北", "高雄"]
        }
    }, {
        "name": "新疆",
        "cities": {
            "city": ["烏魯木齊"]
        }
    }]
}
View Code

由上端的兩段代碼可以看出,JSON簡單的語法格式和清晰的層次結構明顯要比XML容易閱讀,並且在數據交換方面,由於JSON所使用的字符要比XML少的多,可以大大的節約傳輸數據所占用的帶寬

4,AJAX簡介

AJAX(Asynchronous JavaScript And XML)翻譯成中文就是"異步的JavaScript和XML".即使使用JavaScript與服務器進行異步交流, 傳輸的數據為XML(當然,傳輸的數據不只是XML).

AJAX不是新的編程語言,而是一種使用現有標準的新方法.

AJAX最大的優點是在重新不加載頁面的情況下,可以於服務器交換數據並更新部分網頁內容,(這一特點給用戶的感受是在不知不覺中完成請求和訪問的過程)

AJAX不需要任何瀏覽器插件,但需要用戶允許JavaScript在瀏覽器上執行

  1>同步交互:客戶端法一個請求後,需要等待服務器響應結束後,才能發出第二個請求

  2>異步交互:客戶端發出一個請求後,無需等待服務器響應結束,就可以發出第二個請求.

通過AJAX傳輸數據到後端代碼

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>實現字符串的拼接</title>
</head>
<body>
<h1>AJAX的請求響應方式</h1>
{#<input type="text" name="n1">+#}
{#<input type="text" name="n2">=#}
{#<input type="text" name="n3">#}
{#<input type="submit" id="b1">#}
<hr>

<input type="text" name="ii1">+
<input type="text" name="ii2">=
<input type="text" name="ii3">
<input type="submit" id="b2">
<input type="submit" id="b3" value="測試參數">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
{#  第一版,簡單的ajax提交代碼  #}
{#    $("#b1").click(function ()  {          {# 給比這個提交按鈕綁定點擊事件 #}
{#        $.ajax({                            {# 固定寫法,聲明是ajax提交數據 #}
{#            url: "/home/",                  {# 寫明要移交數據的地址,如果是本網站跳轉就寫相對路徑,如果是跨站就寫絕對路徑 #}
{#            type: "post",                   {# 提交數據的類型是post請求, #}
{#            data: {                         {# 要提交的所有數據都放在data中 #}
{#                n1: $("[name=‘n1‘]").val(), {# 獲取到用戶第一個輸入框的內容 #}
{#                n2: $("[name=‘n2‘]").val()  {# 獲取到用戶第二個輸入框的內容 #}
{#            },#}
{#            success: function (res) {      {# success表示接受服務器發過來的處理後的數據,括號要加參數 #}
{#                console.log(res);#}
{#                $(‘[name="n3"]‘).val(res);   {# 把接受到處理後的數據填入到第三個輸入框中,交給瀏覽器渲染 #}
{#            }#}
{#        })#}
{#    });#}
{# 第二版證明每個提交事件是異步的 #}
{#    $("#b2").click(function () {                {# 異步處理,每一個是一個單獨的提交時間 #}
{#        $.ajax({#}
{#            url: "/index/",#}
{#            type: "post",#}
{#            data: {#}
{#                nn1: $("[name=‘ii1‘]").val(),#}
{#                nn2: $("[name=‘ii2‘]").val()#}
{#            },#}
{#            success: function (res) {#}
{#                console.log(res);#}
{#                $("[name=‘ii3‘]").val(res);#}
{#            }#}
{#        })#}
{#    });#}

{# AJAX提交數據可以是序列化的字符串 #}
    
    $("#b3").click(function () {                             {# 給b3按鈕綁定點擊事件 #}
        $.ajax({                                              {# 指定ajax提交數據 #}
            url: "/ajax_test/",                               {# 指定提交的地址 #}
            type: "post",                                     {# 指定提價哦數據的類型 #}

            data: {                                           {# 要提交的數據 #}
                name:"雪雪",
                age:"29",
                hobby:JSON.stringify(["我","購物","看電影"])   {# 提交非字符串類型的數據結構需要stringfy序列化 #}
            },
            success: function (res) {                         {# 接收數據處理後返回的response對象 #}
                console.log(res);
                $("[name=‘ii3‘]").val(res);                    {# 把接收到的數據通過形參res接收到添加到結果框中 #}
            },
            error: function (ret) {                            {# 當視圖函數中有錯誤的時候會走這個error的函數 #}
                console.log(ret);
                console.log("這是錯誤的")
            }
        })
    })
</script>
</body>
</html>    

這是視圖函數的代碼:

from django.shortcuts import render, HttpResponse
import json
# Create your views here.
from django.http import JsonResponse

# def home(request):
#     # 第二次進來,要獲取用戶輸入的值
#     if request.method == "POST":
#         n1 = request.POST.get("n1")
#         n2 = request.POST.get("n2")
#         # 獲取到數據後做拼接
#         n3 = n1 + n2
#         # 把處理後的數據發送給前端並渲染
#         return HttpResponse(n3)
#     # 第一次進來是GET請求,返回給用於一個頁面
#     return render(request, "home.html")

#
# def index(request):
#     # 第二次進來是post提交的請求
#     if request.method == "POST":
#         # 獲取用戶輸入的值
#         nn1 = request.POST.get("nn1")
#         nn2 = request.POST.get("nn2")
#         nn3 = nn1 + nn2
#         # 把獲取到的值發送給瀏覽器已經渲染了的頁面的對應的地方
#         return HttpResponse(nn3)
#     # 第一次進來是GET請求,返回給用於一個網頁
#     return render(request, "home.html")


def ajax_test(request):
    print(123)
    if request.method == "POST":
        # 獲取數據
        # 提交過來的數據是字符串類型需要反序列化
        print(request.POST.get("data"))
        data_dict1 = request.POST.get("name")
        data_dict2 = request.POST.get("age")
        data_dict3 = request.POST.get("hobby")
        print("name:",data_dict1,type(data_dict1))
        print("age:",data_dict2,type(data_dict2))
        print("hobby:",data_dict3,type(data_dict3))
        # msg1 = json.loads(data_dict1)
        # msg2 = json.loads(data_dict2)
        msg3 = json.loads(data_dict3)
        # print(msg1)
        # print(msg2)
        print(msg3[0])
        print(msg3[1])
        print(msg3[2])
    #     print(data_dict3[0])
    #     print(data_dict3[1])
    #     print(data_dict3[2])
    # print(789)
    # return HttpResponse("ok")
        ret = {"status":200,"mag":"ok"}
        int("ajgdh")
        return JsonResponse(ret)
    return render(request, "home.html")

5,AJAX常見應用場景

  搜索引擎根據用戶輸入的關鍵字,自動提示檢索關鍵字.還有一個很重要的應用場景就是註冊時候的用戶名查重.其實這裏就使用了AJAX技術!當文件框發生變化時,使用AJAX技術向服務器發送一個請求,然後服務器會把查詢到的結果響應給瀏覽器,最後再把後端返回的結果展示出來

  • 整個過程中頁面沒有刷新,只是刷新頁面中的局部位置而已!
  • 當請求發出後,瀏覽器還可以進行其他操作,無需等待服務器的響應!

技術分享圖片

當用戶輸入同戶名時,把光標移動到其他表單時,瀏覽器會使用AJAX技術向服務器發出請求,服務器會查詢名為lemontree7777777的用戶是否存在,最終服務器返回true表示名為lemontree7777777用戶已經存在了,瀏覽器在得到結果顯示"用戶名已經被註冊"

  • 整個過程中頁面沒有刷新,只是局部刷新了
  • 在請求發出後,瀏覽器不用等待服務器響應結果就可以進行其他操作

7,AJAX的優缺點:

優點:

  • AJAX使用JavaScript技術向服務器發送異步請求;
  • AJAX請求無須刷新整個頁面
  • 因為服務器響應內容不在是整個頁面,而是頁面中的部分內容,所以AJAX性能高

缺點:

  • 破壞瀏覽器後退按鈕的正常行為,在動態更新頁面的情況下,用戶無法回到前一個頁面.
  • 使用動態頁面更新使得用戶難於將某個特定的狀態保存到收藏夾中
  • 進行AJAX開發時,網絡延遲---->即用戶發出請求到服務器到服務器發出響應之間的時間間隔.

8,AJAX請求如何設置csrf_token

放法1:通過隱藏的input標簽中的csrfmiddlewaretoken值,放在data中發送

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>實現字符串的拼接</title>
</head>
<h1>AJAX的請求響應方式</h1>
<input type="text" name="ii1">+
<input type="text" name="ii2">=
<input type="text" name="ii3">
<input type="submit" id="b2">
{#<input type="submit" id="b3" value="測試參數">#}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script>
    $("#b2").click(function () {
        $.ajax({
            url: "/home/",
            type: "POST",
            data: {
                ii1: $("[name=‘ii1‘]").val(),
                ii2: $("[name=‘ii2‘]").val(),
                csrfmiddlewaretoken: $("[name=‘csrfmiddlewaretoken‘]").val()  // 使用jQuery取出csrfmiddlewaretoken的值,拼接到data中
            },
            success: function (res) {
                console.log(res);
                $("[name=‘ii3‘]").val(res)
            }
        })
    })
</script>
</body>
</html>

方法2:通過獲取返回的cookie中的字符串放置在請求頭中發送.註意:需要引入一個jQuery.cookie.js插件

<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>實現字符串的拼接</title>
</head>
<body>
<h1>AJAX的請求響應方式</h1>
<hr>
{% csrf_token %}
<input type="text" name="ii1">+
<input type="text" name="ii2">=
<input type="text" name="ii3">
<input type="submit" id="b2">
{#<input type="submit" id="b3" value="測試參數">#}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script>
{# ajax法post請求,通過CSRF驗證的第二種方法,先死記住吧!不理解源碼! #}
$("#b2").click(function () {
$.ajax({
url: "/home/",
type: "POST",
headers: {"X-CSRFToken": $("[name=‘csrfmiddlewaretoken‘]").val()}, // 從Cookie獲取csrftoken,並設置到請求頭中
data: {
ii1: $("[name=‘ii1‘]").val(),
ii2: $("[name=‘ii2‘]").val()
},
success: function (res) {
console.log(res);
$("[name=‘ii3‘]").val(res)
}
})
});
/script> </body> </html>

方法3,全局設置:如果使用cookie從cookie中取值,必要有cookie有cookie的方式,確保cookie存在csrftoken值

  • 使用{% csrf_token %}
  • 不使用{% csrf_token %}
    •   --->from django.views.decoration.csrf import ensure_csrf_cookie
    • --->ensure_csrf_cookie加在試圖函數上,保證返回的響應有cookie
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>實現字符串的拼接</title>
</head>
<body>
<h1>AJAX的請求響應方式</h1>

<hr>
{% csrf_token %}
<input type="text" name="ii1">+
<input type="text" name="ii2">=
<input type="text" name="ii3">
<input type="submit" id="b2">
{#<input type="submit" id="b3" value="測試參數">#}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="/static/ajax_setup.js"></script>
<script>

    {# ajax發送post請求,通過CSRF驗證的第三種方法,先死記住吧!不理解源碼 #}

    $("#b2").click(function () {
        $.ajax({
            url:"/home/",
            type:"post",
            data:{
                ii1:$("[name=‘ii1‘]").val(),
                ii2:$("[name=‘ii2‘]").val(),
            },
            success: function (data) {
                console.log(data);
                $("[name=‘ii3‘]").val(data)
            }
            })
        })

</script>
</body>
</html>
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);
    }
  }
});

試圖函數的代碼:

from django.shortcuts import render, HttpResponse
import json
# Create your views here.
from django.http import JsonResponse
from django.views.decorators.csrf import ensure_csrf_cookie


# @ensure_csrf_cookie
def home(request):
    # 第二次進來,要獲取用戶輸入的值
    if request.method == "POST":
        ii1 = request.POST.get("ii1")
        ii2 = request.POST.get("ii2")
        print(ii1)
        print(ii2)
        # 獲取到數據後做拼接
        ii3 = ii1 + ii2
        # 把處理後的數據發送給前端並渲染
        return HttpResponse(ii3)
    # 第一次進來是GET請求,返回給用於一個頁面
    return render(request, "home.html")

#
# def index(request):
#     # 第二次進來是post提交的請求
#     if request.method == "POST":
#         # 獲取用戶輸入的值
#         nn1 = request.POST.get("nn1")
#         nn2 = request.POST.get("nn2")
#         nn3 = nn1 + nn2
#         # 把獲取到的值發送給瀏覽器已經渲染了的頁面的對應的地方
#         return HttpResponse(nn3)
#     # 第一次進來是GET請求,返回給用於一個網頁
#     return render(request, "home.html")


def ajax_test(request):
    print(123)
    if request.method == "POST":
        # 獲取數據
        # 提交過來的數據是字符串類型需要反序列化
        print(request.POST.get("data"))
        data_dict1 = request.POST.get("name")
        data_dict2 = request.POST.get("age")
        data_dict3 = request.POST.get("hobby")
        print("name:",data_dict1,type(data_dict1))
        print("age:",data_dict2,type(data_dict2))
        print("hobby:",data_dict3,type(data_dict3))
        # msg1 = json.loads(data_dict1)
        # msg2 = json.loads(data_dict2)
        msg3 = json.loads(data_dict3)
        # print(msg1)
        # print(msg2)
        print(msg3[0])
        print(msg3[1])
        print(msg3[2])
    #     print(data_dict3[0])
    #     print(data_dict3[1])
    #     print(data_dict3[2])
    # print(789)
    # return HttpResponse("ok")
        ret = {"status":200,"mag":"ok"}
        int("ajgdh")
        return JsonResponse(ret)
    return render(request, "home.html")

    

AJAX請求提交數據