AJAX請求提交數據
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請求提交數據