第九节 Ajax

一 Ajax技术简介

AJAX(Asynchronous Javascript And XML)异步Javascript和XML
(传输的数据不只是XML,现在更多的使用json数据格式)

# 他属于是前端的内容,不属于Python范围的,但是它必须结合后端来使用,否则也没有太大的意义,因为它是把前端的数据提交到后端的

# form表单来提交数据到后端,但是,它每次提交数据都需要刷新页面,刷新页面会让用户的体验感不好

"""
	Ajax技术就是局部刷新,异步提交,它不需要刷新整个页面,只需要刷新局部的,主要刷新的时候是无感知的
	Ajax的特点:局部刷新,异步提交
"""
同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求,同步提交需要等待结果
异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求,异步提交不需要等待结果
    

案例:Github的注册案例

基于jquery的Ajax实现
# 我们知道Ajax它属于js语言,所以它肯定能够使用js实现,但是,js实现太麻烦了,总共分四个步骤
# 我们不学学习js版本的ajax,我们学习jQuery封装之后的Ajax,把Ajax的使用表的非常简单
23种设计模式:单例模式,工厂模式,注册树模式等等

二 案例

# 我们使用的ajax是jQuery封装之后的版本,所以,要想使用Ajax必须导入jQuery库

# 让你做一个加法运算
// 需求:把前端输入的值提交到后端计算
// 如何把输入的值提交到后端------>使用ajax提交
<input type="text" id="d1">+
<input type="text" id="d2">=
<input type="text" id="d3">
<button class="btn btn-info">计算</button>

<script>
        $.ajax({
            // 1. 指定参数提交到后端的哪个地址?
            url:'',  // 如果不写就是朝当前地址提交

            // 2. 指定以什么请求方式提交的 get post
            type:'post',

            // 3. 指定要传递的数据
            {#data: {'d1':d1, 'd2':d2},#}
            data: {d1:d1, d2:d2},
            
            dataType:'json' # 前端不反序列化,需要指定参数
            // 4. 回调函数,接收后端返回的数据
            success:function (res) {
                // 怎么样反序列化?
                {#console.log(res);#}
                {#console.log(typeof res);#}
                {#console.log(res.code);#}

                {#res= JSON.parse(res) // 对象#}
                {onsole.log(res);#}//在控制台打印上
                #$("#d3").val(res);//让值显示在页面上
            }
        })
</script>

views.py:

    def index(request):
    if request.method=='POST':
    # print(request.is_ajax())  # True False
        # 接收参数
        d1=request.POST.get('d1')
        d2=request.POST.get('d2')

        # 做运算
        d3 = int(d1)+int(d2)
        return HttpResponse(d3)
    return render(request,'index.html')

三 Ajax的高阶用法

3.1.方式一:后端使用return HttpResponse(res),前端需要自己反序列化:res= JSON.parse(res)

views.py:
def index(request):
    if request.method=='POST':
    d = {'code':200,'msg':'请求成功','data':{'username':'jerry'}}
	
        import json
        res = json.dumps(d,ensure_ascii=False) # 序列化
        return HttpResponse(res)
    return render(request,'index.html')

index.html:
            //4.回调函数,接收后端返回的数据
            success:function (res){
                res = JSON.parse(res)# 反序列化
                console.log(res.data.username);

3.2.方式二:后端如果使用return JsonResponse(d), 前端不用反序列化,直接当成对象使用

from django.http import JsonResponse
views.py:
def index(request):
    if request.method=='POST':
    d = {'code':200,'msg':'请求成功','data':{'username':'jerry'}}
        return JsonResponse(d)
	return render(request,'index.html')
                
index.html:
            success:function (res){
                console.log(res);# 这里得到的res是对象

3.3.方式三:后端使用return HttpResponse(res),前端不反序列化,需要指定参数:dataType:'json'

views.py:
def index(request):
    if request.method=='POST':
    d = {'code':200,'msg':'请求成功','data':{'username':'jerry'}}
        return HttpResponse(d)
	return render(request,'index.html')
         
index.html:
             dataType:'json',
            //4.回调函数,接收后端返回的数据
            success:function (res){
                console.log(res.code)
            }

总结:
1. 后端如果使用return JsonResponse(d), 前端不用反序列化,直接当成对象使用
2. 后端使用return HttpResponse(res),前端需要自己反序列化:res= JSON.parse(res)
3. 后端使用return HttpResponse(res),前端不反序列化,需要指定参数:dataType:'json'

四 前后端数据传输的编码格式(contentType)

1.前后端数据传输的时候请求方式有2种:get post

我们不研究get请求 get请求的没有数据的编码格式
get 请求的参数一般在 url?a=1&b=2

2.我们只研究post请求的编码格式
三种编码格式:
    urlencoded
    form-data
    json

3.可以通过哪些方式发送post请求
form表单
Ajax
postman

4.请求头中的Content-Type:参数  表示编码格式

5.研究form表单发送post请求的时候数据的编码格式
	默认提交编码格式是:application/x-www-form-urlencoded
	它的数据格式是:username=dasdas&password=dasdas&gender=dasdas

	针对application/x-www-form-urlencoded格式的数据,在Django后端是如何接收数据的
	Django后端针对符合urlencoded格式的数据,django把数据都封装到了request.POST中了

6.编码格式:multipart/form-data
  编码格式从urlencoded改成form-data有什么效果?
	form表单就可以提交文件数据了
	数据格式:
		Content-Type:
	multipart/form-data; boundary=----WebKitFormBoundary7iwnnLo3TDiHIAQz--->文件数据
	文件数据就是二进制数据(boundary)

	针对multipart/form-data格式的数据,Django后端是如何接收数据的
		针对普通数据django把数据封装到了request.POST中
		针对文件数据django把数据封装到了reuqest.FILES中

7.Ajax提交post请求的数据时候,编码格式又是怎样的?
	默认的提交格式是:application/x-www-form-urlencoded; 
	Django后端针对符合urlencoded格式的数据,django把数据都封装到了request.POST

五 Ajax提交json格式的数据

1.提交json格式的数据必须满足两个条件:
	1.1 你的编码格式必须是json格式的:contentType参数
	1.2 你的数据必须是json {"a":1}
 
2.针对json格式的数据,Django后端又是如何处理的?
	2.1针对ajax提交的json格式的数据,django后端不再把数据封装到request.POST中了
	2.2对于json格式的数据,django后端不在做任何的封装,数据是纯原生的,发送过来的数据是二进制形式的
    2.3.我们自己来处理这些二进制数据

3.补充:
# js中序列化
    data: JSON.stringify({'a': 1, b: 2}), //序列化,将数据转成json格式
    contentType:'application/json', //指定urlencoded编码格式

4.django后端接收json格式的数据
def index(request):
    print(request.POST)  # <QueryDict: {}>
    print(request.body)  # b'{"a":1,"b":2}'

    # 方式一:
    json_str = request.body.decode('utf-8')
    print(json_str)  # {"a":1,"b":2}

    if request.method == 'POST':
        json_data = json.loads(json_str)
        print(json_data.get('a'))  # 1

    # 方式二:
    if request.method == 'POST':
        json_bytes = request.body # 字节类型
        json_data= json.loads(json_bytes)  # 如果是二进制可以直接反序列化
        print(json_data)   # {'a': 1, 'b': 2}

    return render(request, 'index.html')

六 Ajax提交文件数据(重要)

var username = $("#username").val();
var password = $("#password").val();

// 文件数据
{#var myfile = $("#myfile")[0].files[0];#}
    var myfile= $("#myfile")[0].files[0]; 

// 发送文件数据到后端需要借助于FormData对象
var myFormDataObj = new FormData();
myFormDataObj.append('username', username);
myFormDataObj.append('password', password);
myFormDataObj.append('myfile', myfile);

    $.ajax({
        url: '',
        type: 'post',
        data: myFormDataObj, // {}
        contentType:false, // 告诉浏览器不要做任何的编码格式处理,django自己来做处理
        processData:false, // 告诉浏览器不要对我处理的数据做任何的处理
        success: function (res) {
            {#console.log(res)#}
            }
        });

六 AJax结合layer弹窗实现删除的二次确认

# 我们使用第三方的UI弹窗:layer、sweetalert、
https://layuiweb.com/doc/element/form.html ----------> layui    
https://layuiweb.com/layer/index.htm---------------->layer

<tr class="tr_{{ book_obj.pk }}">

<a href="#" class="btn btn-danger" delete_id='{{ book_obj.pk }}' >删除</a>    # 这里href="#"是为了让删除不要跳转页面,还可以通过删除href="",或者href="javascript:;"

   $('.btn').click(function () {
        var id = $(this).attr('delete_id') //attr:获取属性
        var _this=$(this)
        layer.confirm('你确定要删除这条数据吗?', {
            btn: ['确定'] //按钮
        }, function () {
            // 发送ajax请求
            $.ajax({
                url: '/book/delete/',
                type: 'post',
                data: {'id': id},
                success: function (res) {
                    if (res.code == 200) {
{% comment %}     layer.msg(res.msg,{icon:2},function (){
                        location.reload()
                        });{% endcomment %} //第二个参数是图标,可以通过改变图标参数,更新图标样式;把刷新放在匿名函数里,放完之后就会先执行删除,成功提醒,再执行刷新,还可以通过直接删除tr标签,不用刷新也删除成功
                        layer.msg(res.msg);
             #方式一:需要提前定义变量_this,拿到a标签,再拿到tr标签 $(_this).parent().parent().remove()
              # 方式二:通过获取类名拿到tr标签
                        {#$('.tr_'+ id).remove();#}
                    }
                }
            });
        });
    })
</script>
posted @ 2023-08-12 21:05  瓜瓜不甜  阅读(54)  评论(0)    收藏  举报