Django与Ajax

Django与Ajax

一 Ajax介绍

1 什么是Ajax

	AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步Javascript和XML”。即使用Javascript语言与服务器进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)。
# 异步 Javascript 和 XML
-异步:跟同步是对应的   
-javascript:通过javascript来操作,发送请求 ,到服务端
-xml:数据交互使用xml,现在主流使用json格式

# xml 与 json
-xml:可阅读性比较高,解析复杂,占的空间大
	<name>lqz</name>
	<age>19</age>
-json:可阅读性比较高,解析简单,占的空间小
	{"name":"lqz","age":19}

# 优点:
-浏览器页面**局部刷新**(js的dom(Document Object Model)操作)
-通过js发送http的请求(go,java,php,requset)

2 同步与异步交互

-同步交互:客户端发出一个请求后,需要等待服务器响应结束后,才能发出第二个请求;
-异步交互:客户端发出一个请求后,无需等待服务器响应结束,就可以发出第二个请求。

二 基于jQuery的Ajax实现

# 需求:通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面

# 模板
    $.ajax({
        url: '/add/',  
        method: 'post',
        data:{'a':$("#first").val() ,'b':$("#second").val() },
        success:function (data) {
            //成功触发
        },
        error:function (error) {
            //失败,触发
        }
    })
    
    
    # 默认情况下ajax会把{'a':$("#first").val() ,'b':$("#second").val() }数据转成
    # 预处理数据
    a=20&b=30,放到body体中
    # 编码默认用urlencoded

Ajax---->服务器------>Ajax执行流程图

三 案例

1 通过Ajax,实现前端输入两个数字,服务器做加法,返回到前端页面

视图函数

# 视图函数
def index(request):
    return render(request, 'index.html')

def add(request):
    # if request.is_ajax():
    if request.method == 'POST':
        # 取出a和b
        a = int(request.POST.get('a'))
        b = int(request.POST.get('b'))
        print(a, b)

        # HttpResponse返回什么,js中的data就是什么
        return HttpResponse(a + b)

js代码

# js代码
// 借助jquery封装好的ajax方法,发送ajax请求
    // 点击button按钮,触发Ajax请求
    $('#btn').click(function () {
        $.ajax({
            url: '/add/',  // 向那个地址发送请求
            method: 'post',  // 发送请求类型
            // 使用jQuery,获取输入框内的值
            // 向后端传输的数据(没有指定编码,默认使用urlencoded)
            data: {'a': $('#first').val(), 'b': $('#second').val()},
            // 数据正常返回,就会触发该匿名函数的执行,返回的数据就会赋值给data
            success: function (data) {
                console.log(data)
                // 把后端返回的数据,通过DOM操作,写到input框中
                $('#result').val(data)
            },
            // 请求失败,就会触发error的执行,并且会把错误信息给error
            error: function (error) {
                console.log(error)
            }
        })
    })

html代码

# html代码
<input type="text" id="first"> + <input type="text" id="second"> = <input type="text" id="result">
<p><button id="btn">计算结果</button></p>

2 基于Ajax进行登录验证

	用户在表单输入用户名与密码,通过Ajax提交给服务器,服务器验证后返回响应信息,客户端通过响应信息确定是否登录成功,成功,则跳转到首页,否则,在页面上显示相应的错误信息

视图函数

# 视图函数
def auth(request):
    back_dic = {'user': None, 'message': None}
    name = request.POST.get('name')
    password = request.POST.get('password')
    print(name)
    print(password)
    user = models.User.objects.filter(name=name, password=password).first()
    print(user)
    # print(type(user))
    if user:
        back_dic['user'] = user.name
        back_dic['message'] = '登录成功'
    else:
        back_dic['message'] = '用户名或密码错误'
    import json
    return HttpResponse(json.dumps(back_dic))

js代码

# js代码
	$('#btn_json_hw02').click(function () {
        $.ajax({
            url:'/auth/',
            method:'post',
            // jquery 从输入框中拿到数据,组成data,传输给后端去判断
            data:{name:$('#hw_user').val(),password:$('#hw_pwd').val()},
            // 数据正常返回,就会触发该匿名函数的执行,返回的数据就会赋值给data
            success:function (data) {
                // console.log(data)
                // console.log(typeof data)
                var data=JSON.parse(data)
                // 判断返回的数据中的内容
                if (data.user){
                    location.href='http://www.baidu.com'
                    //console.log(data.message)
                } else{
                alert(data.message)
            }
            },
        })
    })

四 Ajax文件上传

1 请求头ContentType的三种编码

(1) application/x-www-form-urlencoded

-最常见的 POST 提交数据的方式。浏览器的原生 <form> 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。请求类似于下面这样(无关的请求头在本文中都省略掉了):

POST http://www.example.com HTTP/1.1
Content-Type: application/x-www-form-urlencoded;charset=utf-8

user=lxx&age=2

(2) multipart/form-data

-又一个常见的 POST 数据提交的方式。我们使用表单上传文件时,必须让 <form> 表单的 enctype 等于 multipart/form-data。直接来看一个请求示例:
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA

------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="user"

yuan
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png

PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--

-这个例子稍微复杂点。首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 multipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 --boundary 开始,紧接着是内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 --boundary-- 标示结束。关于 multipart/form-data 的详细定义,请前往 rfc1867 查看。

-这种方式一般用来上传文件,各大服务端语言对它也有着良好的支持。

-上面提到的这两种 POST 数据的方式,都是浏览器原生支持的,而且现阶段标准中原生 <form> 表单也只支持这两种方式(通过 <form> 元素的 enctype 属性指定,默认为 application/x-www-form-urlencoded。其实 enctype 还支持 text/plain,不过用得非常少)。

-随着越来越多的 Web 站点,尤其是 WebApp,全部使用 Ajax 进行数据交互之后,我们完全可以定义新的数据提交方式,给开发带来更多便利。

(3) application/json

application/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。

JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。

2 基于Form表单上传文件

# 视图函数
def uploadfile(request):
    file = request.FILES.get('myfile')
    name = request.POST.get('name')
    # print(name)
    with open(file.name, 'wb') as f:
        for line in file:
            f.write(line)
    return HttpResponse('上传成功!')
# html代码
<h1>通过form表单上传文件</h1>
<form action="/uploadfile/" method="post" enctype="multipart/form-data">
    <p><input type="file" name="myfile"></p>
    <p>用户名:<input type="text" name="name"></p>
    <input type="submit" value="提交">
</form>

3 基于Ajax上传文件

3.1 基于Ajax上传文件的模板

固定模板

# 固定模板
    var formdata=new FormData() 
    formdata.append('myfile',$("#id_file")[0].files[0])
    # 还可以带数据
    $.ajax({
            url:'/uploadfile/',
            method: 'post',
            //上传文件必须写这两句话
            processData:false,  # 预处理数据,
            contentType:false,  # 不指定编码,如果不写contentType,默认用urlencoded
            data:formdata,      # formdata内部指定了编码,并且自行处理数据
            success:function (data) {  
                console.log(data)
            }
        })

视图函数

# 视图函数
def uploadfile(request):
    file = request.FILES.get('myfile')
    name = request.POST.get('name')
    # print(name)
    with open(file.name, 'wb') as f:
        for line in file:
            f.write(line)
    return HttpResponse('上传成功!')

js代码

# js代码
// 借助jquery封装好的ajax方法,发送ajax请求
    // 点击button按钮,触发Ajax请求
    // ajax上传文件
    $('#btn_file').click(function () {
        var formdata=new FormData()  // 实例化得到一个formdata对象
        // 把文件放到对象内
        // formdata.append('myfile', 文件对象)
        formdata.append('myfile', $('#id_file')[0].files[0])
        // formdata也可以存放数据
        formdata.append('name', $('#id_name').val())
        $.ajax({
            url:"/uploadfile/",
            method:'post',
            // 上传文件必须写这两句话
            processData:false,
            contentType:false,
            data:formdata,
            success:function (data) {
                alert(data)
            }
        })
    })

html代码

# html代码
<h1>通过Ajax上传文件</h1>
    <p><input type="file" id="id_file"></p>
    <p>用户名:<input type="text" id="id_name"></p>

    <button id="btn_file">提交</button>

4 总结

-无论是使用Form表单上传文件,还是使用Ajax或者postman上传,后端的视图代码都不需要改变,只是改变前端部分的代码即可。Ajax异步请求,不用等待操作是否成功。

五 Ajax提交json格式数据

# 提交到服务器的数据都在 request.body 里,取出来自行处理。
$.ajax({
            url:'/uploajson/',  //写全,是什么样就写什么样
            method:'post',
            contentType: 'application/json',
            //data要是json格式字符串
            //data:'{"name":"","password":""}',
            //把字典转成json格式字符串
            //JSON.stringify(dic)
            //把json格式字符串转成对象
            //JSON.parse(data)
            data:JSON.stringify({name:$("#id_name1").val(),password:$("#id_password1").val()}),
            success:function (data) {
                //返回字符串类型,需要转成js的对象,字典
                //1 如果:django 返回的是HttpResponse,data是json格式字符串,需要自行转成字典
                //2 如果:django 返回的是JsonResponse,data是就是字典
                //ajax这个方法做的是,如果响应数据是json格式,自动反序列化
                console.log(typeof data)
                var res=JSON.parse(data)
                console.log(typeof res)
                console.log(res.status)
                console.log(res.msg)
            }
        })

视图函数

# 视图函数
from django.http import JsonResponse
def uploadjson(request):
    data = request.body
    print(data)
    dic = {'status': 100, 'msg': '成功'}

    print(request.POST)  # 没有数据,
    import json
    return HttpResponse(json.dumps(dic))
    # return JsonResponse(dic)

js代码

# js代码
// 借助jquery封装好的ajax方法,发送ajax请求
    // 点击button按钮,触发Ajax请求
	// Ajax提交json格式数据
    $('#btn_json').click(function () {
        $.ajax({
            url:'/uploadjson/',
            method:'post',
            contentType:'application/json',
            // data如果是json格式字符串
            // data:'{"name":"","password":""}'
            // 把字典转换成json格式字符串
            // JSON.stringfy(dic)
            // 把json格式字符串转成对象
            // JSON.parse(data)
            data:JSON.stringify({name:$('#id_name1').val(), password:$('#id_password1').val()}),
            success:function (data) {
                // 返回字符串类型,需要转成js的对象、字典
                //1 如果:django 返回的是HttpResponse,data是json格式字符串,需要自行转成字典
                //2 如果:django 返回的是JsonResponse,data是就是字典
                //ajax这个方法做的是,如果响应数据是json格式,自动反序列化
                console.log(data)
                console.log(typeof data)
                // var res = JSON.parse(data)
                // console.log(typeof res)
                // console.log(res.status)
                // console.log(res.msg)
            },
            error:function (error) {
                console.log(error)
            },
        })
    })

html代码

# html代码
<h1>通过Ajax提交json格式数据</h1>
    <p>用户名:<input type="text" id="id_name1"></p>
    <p>密码:<input type="text" id="id_password1"></p>

    <button type="submit" id="btn_json">提交</button>

六 了解Django内置序列化器serializers

Django内置的serializers可以把对象序列化程json字符串

1) 把对象转成json格式,json.dumps实现不了,
2) django内置了一个东西,可以把对象转成json格式
from django.core import serializers
book_list = Book.objects.all()    
ret = serializers.serialize("json", book_list)  # ret就是json格式字符串

"""自己写,有局限,不通用
ll=[]
for book in book_list:
    ll.append({'name':book.name,'price':book.pirce})  
import json
ret=json.dumps(ll)
"""

return HttpResponse(ret)  
# [{"model": "ajax_test.user", "pk": 1, "fields": {"name": "lxx", "password": "123"}}]
# django内置的返回值,内容较多,需进一步处理

七 其他补充

1 js逆向,混淆和压缩

#待填坑

2 IAAS,PAAS,SAAS

1 IaaS: Infrastructure-as-a-Service(基础设施即服务)

-即开发公司自己搭设服务器,然后在上面开发软件,提供软件服务给用户。

2 PaaS: Platform-as-a-Service(平台即服务)

-开发公司购买服务器供应商的平台,在其上开发软件,再提供软件服务给用户。

3 SaaS: Software-as-a-Service(软件即服务)

-用户不再购买然软件,直接向大型互联网公司购买web服务及配套的服务器等等。
posted @ 2021-06-26 05:19  越关山  阅读(77)  评论(0)    收藏  举报