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服务及配套的服务器等等。

浙公网安备 33010602011771号