Ajax基本使用和JsonHttpResponse

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")
        return HttpResponse("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类型,那么我们需要自行解析

‘‘‘

 

Ajax基本使用和JsonHttpResponse

上一篇:小谢第46问:js事件机制


下一篇:JWT——json web token