Ajax基本使用和JsonHttpResponse
阿新 • • 發佈:2020-07-23
Ajax :非同步請求,不會重新整理頁面,頁面上使用者之前輸入的資料都不會丟失。
簡單請求案例:
views頁面
from django.shortcuts import render,HttpResponse,redirect from django.urls import reverse def login(request): if request.method == "POST": if request.POST.get("uname") == "root": return HttpResponse("ok") returnHttpResponse("error") return render(request, "login.html") def home(request): return render(request,"home.html")
HTML頁面
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body><div> <label> 使用者名稱: <input type="text" name="username" id="username"> </label> <label> 密碼: <input type="password" name="password" id="password"> </label> <button id="btn">提交</button> <span style="color: red;font-size: 12px"id="err"></span> </div> </body> <script src="{% static 'js/jquery.js' %}"></script> <script> $('#btn').click(function (){ var name = $('#username').val(); var pwd = $('#password').val(); console.log(name,pwd) $.ajax({ url: {% url 'login' %}', type: 'post', data: {uname:name,upwd:pwd}, success: function (res) { console.log(res, typeof res) if(res==="ok"){ location.href = '{% url 'home' %}'; } else{$('#err').text("使用者名稱或者密碼錯誤") } } }) }) </script> </html>
注意點:
$.ajax({ //
url:'/login_ajax/', //寫路徑時,如果後臺使用的是django框架,那麼url路徑的後面的斜槓要加上,如果想不加上斜槓,
那麼需要在django的settings配置檔案中加上 APPEND_SLASH = False,並且後臺的urls.py檔案中的路徑要和ajax請求路徑對應好,
該有斜槓寫斜槓,不需要斜槓的,去掉斜槓
type:'post',
...
}),
在js程式碼中客戶使用url別名反向解析來寫路徑:
$.ajax({ //
url:'{% url "login_ajax" %}',
type:'post',
...
}),
但是,要注意一點,當這段js程式碼是寫到某個js檔案中,然後hmtl檔案通過script標籤的src屬性來引入時,
{% url "login_ajax" %}語法就不能被模板渲染了,也就是失效了
響應字典資料型別
方式一:手動利用json序列化和反序列化
views頁面
from django.shortcuts import render,HttpResponse,redirect from django.urls import reverse from django.http import JsonResponse def login(request): if request.method == "POST": if request.POST.get("uname") == "root": return HttpResponse("ok") return HttpResponse("error") return render(request, "login.html") def home(request): return render(request,"home.html") def data(request): import json dic = {"summer":["夏日驚喜","西瓜","哈密瓜","涼麵"]} dic_str = json.dumps(dic,ensure_ascii=False) return HttpResponse(dic_str)
HTML頁面
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>這是home頁面</h1> <button id="btn_home">點選有驚喜</button> <ul> </ul> </body> <script src="{% static 'js/jquery.js' %}"></script> <script> $('#btn_home').click(function () { $.ajax({ url: '{% url "data" %}', type: 'get', success: function (res) { console.log(res, typeof res) // 夏天 string 用HttpResponce傳遞字典資料, 只能取到字典的鍵 // 引入json模組後得到字串形式的字典: {"summer": ["西瓜", "哈密瓜", "涼麵"]} string var dic_res = JSON.parse(res) console.log(dic_res,typeof dic_res) var ret = dic_res.summer // 將列表中的內容放到頁面中 for (var i=0;i<ret.length;i++){ var content = ret[i]; var liEle = document.createElement('li'); liEle.innerText = content $('ul').append(liEle); } } }) }) </script> </html>
# 第一種方式,直接通過HttpResponse回覆字典資料,那麼ajax接受到資料之後,需要自行反序列化
# data_list_str = json.dumps(data_list, ensure_ascii=False)
# 直接使用HttpResponse回覆字典型別資料,那麼會將字典裡面元素的鍵都拼接成一個字串來響應,所以不是我們想要的結果,所以我們先將字典型別資料,轉換成json字串,在通過HttpResponse來進行響應
方式二:手動加響應頭鍵值對['content-type'] = 'application/json'
# data函式改寫 def data(request): import json dic = {"summer":["夏日驚喜","西瓜","哈密瓜","涼麵"]} dic_str = json.dumps(dic,ensure_ascii=False) ret = HttpResponse(dic_str) ret['content-type'] = 'application/json' return ret # HTML接收和顯示資料修改 success: function (res) { console.log(res, typeof res) // 夏天 string 用HttpResponce傳遞字典資料, 只能取到字典的鍵 // 引入json模組後得到字串形式的字典: {"summer": ["西瓜", "哈密瓜", "涼麵"]} string {#var dic_res = JSON.parse(res)#} {#console.log(dic_res,typeof dic_res)#} var ret = res.summer // 將列表中的內容放到頁面中 for (var i=0;i<ret.length;i++){ var content = ret[i]; var liEle = document.createElement('li'); liEle.innerText = content $('ul').append(liEle);
#第二種方式:通過HttpResponse回覆字典資料,回覆之前,加上一個響應頭鍵值對,如下,那麼ajax收到這個響應資料的時候,
會檢視這個響應頭,發現content-type這個響應頭的值為application/json,那麼會自動對響應資料進行反序列化,不需要我們自己手動反序列化了
方式三:引入JsonHttpResponce
# data部分 from django.http import JsonResponse def data(request): import json dic = {"summer":["夏日驚喜","西瓜","哈密瓜","涼麵"]} # dic_str = json.dumps(dic,ensure_ascii=False) # ret = HttpResponse(dic_str) # ret['content-type'] = 'application/json' return JsonResponse(dic)
#JsonResponse:1 序列化資料 2 加上['content-type'] = 'application/json'這個響應頭鍵值對
注意:
lst = ["夏日驚喜","西瓜","哈密瓜","涼麵"] #當使用JsonResponse回覆非字典型別資料時,需要將safe引數的值改為False, 不然會報錯 return JsonResponse(lst, safe=False)
區域性更新資料案例:
views頁面
def sub(request): if request.method == "GET": return render(request,"sub.html") else: import json print(request.body) data = request.body.decode() print(data) data = json.loads(data) print(data) a = int(data["a"]) b = int(data["b"]) ret = a+b print(ret) return HttpResponse(ret)
HTML頁面
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <label> a: <input type="text" name="a" id="aid"> </label> <label> b: <input type="text" name="b" id="bid"> </label> <button id="btn_sub">查詢</button> <br> a+b= <span id="sp" style="color: burlywood"></span> </body> <script src="{% static 'js/jquery.js' %}"></script> <script> $('#btn_sub').click(function () { var a = $('#aid').val(); var b = $('#bid').val(); $.ajax({ url: '{% url 'sub' %}', type: 'post', headers: { 'Content-Type':'application/json', }, data: JSON.stringify({a:a,b:b}), success: function (res) { {#alert(res);#} $('#sp').text(res) } }) }) </script> </html>
請求頭訊息格式分析
請求訊息格式和請求方法沒有關係,和請求頭鍵值對中的這一組鍵值對有關係
file說明 <!-- enctype="multipart/form-data"這個引數就是將本次請求的訊息格式,也就是那個content-type的值改為multipart/form-data,
那麼本次http請求,會將檔案資料片段傳送 -->
Content-Type: application/x-www-form-urlencoded; //瀏覽器傳送資料ajax或者form表單,預設的格式都是它 它表示請求攜帶的資料格式,application/x-www-form-urlencoded對應的資料格式是:a=1&b=2
'''
socket 接收到我們請求資料,會分析一下Content-Type: application/x-www-form-urlencoded;這個請求頭
# 叫做解析器
if Content-Type == 'application/x-www-form-urlencoded':
data = 'a=1&b=2'
l1 = data.split('&') [a=1,b=2]
for i in l1:
k,v = i.split('=')
if 請求方法 == 'GET':
request.GET[k] = v
elif Content-Type == 'multipart-formdata':
request.FILES
#django沒有內建對appcation/json的訊息格式的解析器,所以如果請求資料是json型別,那麼我們需要自行解析
'''