Django | 前后端传输数据的编码格式(contentType)
前后端传输数据的编码格式(contentType)
数据传递转码:
数据在传输的过程中,浏览器会对数据进行编码,假如我现在有一条数据 {"name": "gary"},如果我们通过 get 方法传递数据,这条数据会被拼接到 url 请求的后面,如:localhost:8080/src/text.html?name=gary。
post请求编码格式:
# 我们主要来研究post请求前后端传输数据的编码格式
因为GET请求的编码格式显示在路由?后面的参数位置
eg:
username=gary&password=123
# 我们就可以看出来get请求的编码格式
前后端传输数据的编码格式有哪些:
# 常用的就是这三种:
urlencoded
formdata
json
朝后端发送post请求的方式有几种:
# form表单 :method = 'POST'
# Ajax :type = 'post'
# 我们就来研究他们两个在传输数据的时候编码的不同而产生数据格式的不同。
# 研究他们到底是什么编码格式
准备工作:
urls.py
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/',views.index)
]
views.py
def index(request):
if request.method = 'POST':
print('request.POST')
print('request.FILES') # 要注意这里大打印操作,下述会用到他们的打印结果
return render(request,'index.html')
html页面
<form action="" method="post"> # 指定请求方式
<p>username: <input type="text" name="username" class="form-control"> </p>
<p>password: <input type="password" name="password" class="form-control"></p>
<input type="submit" class="btn btn-success">
</form>
研究form表单
urlencoded:
# 在我们向后端提交post请求的时候我们可以看到,post请求的默认编码格式是urlencoded
那么urlencoded编码的数据格式,他的数据到底长什么样子呢?
# 数据格式:
username=gary&password=123&file=%E7%9F%A5%E8%AF%86%E7%82%B9.pdf
# 我们发现urlencoded编码的数据格式和GET请求的编码格式出来的数据格式几乎是一致的
# 后端接收到到的数据格式 :
<QueryDict: {'username': ['gary'], 'password': ['123'], 'file': ['知识点.pdf']}>
<MultiValueDict: {}>
form-data:
# 前端form表单添加属性:enctype="multipart/form-data"
<form action="" method="post" enctype="multipart/form-data">
# 后端接收到的数据:
<QueryDict: {'username': ['gary'], 'password': ['123']}>
<MultiValueDict: {'file': [<InMemoryUploadedFile: 知识点.pdf (application/pdf)>]}>
结论:
django后端针对符合urlencoded编码格式的数据都会自动帮我们解析封装到request.POST中
# 这要数据格式是这样子的:username=jason&password=123
都会解析到 >>> request.POST里面(包括文件数据)
如果你把编码格式改成formdata,那么针对普通的键值对还是解析到request.POST中,而将文件解析到request.FILES中
# form表单是无法发送json格式的数据的。只可以发送urlencoded和form-data
研究Ajax:
准备工作:
<input type="button" class="btn btn-danger" value="按钮" id="d1">
</form>
<script>
$('#d1').click(function (){
$.ajax({
url:'',
type:'post',
data:{'username':'gary','age':19},
success:function(){
}
})
})
</script>
# 创建一个普通按钮,触发点击事件,超后端发送Ajax
结论:
# 我们可以看到ajax也使用的是urlencoded编码格式,并且后端也使用的是request.POST接收数据
# 数据格式:username=gary&age=19
# 所以更加证实了:
django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中
# 并且ajax也是支持发送json格式数据和文件格式数据的
Ajax发送json格式数据
指定编码格式:
# Ajax默认的为urlencoded编码格式
# 但是可以使用contentType指定编码格式。
<input type="button" class="btn btn-success" value="按钮" id="d1">
<script>
$('#d1').click(function (){
$.ajax({
url:'',
type:'post',
data:{'username':'gary','age':19},
contentType:'application/json', # 指定编码格式json,全称:application/json
success:function (){
}
})
})
</script>
遵循条件
# 前后端在传输数据的时候一定要确保编码格式跟数据正真的格式是一致的。
data:JSON.stringify({'username':'gary','age':19}), # 前端序列化
# 上述我们验证过只有urlencoded编码格式的数据才会自动帮你解析封装到request.POST中
那么我们来看一下是否可以接收:
# 就更加验证了
django后端针对符合urlencoded编码格式的数据都会自动帮你解析封装到request.POST中
# django针对json格式的数据 不会做任何的处理
request对象方法补充:
# request.is_ajax()
# 判断当前请求是否是ajax请求 返回布尔值
# request.body
# 接收二进制类型的数据
# 因为接受的是二进制类型那么在针对json格式的字符串,需要我们手动的处理:
import json
def db_json(request):
if request.is_ajax():
res = request.body # 拿到二进制类型的json类型字符串
json_str = res.decode('utf-8') # 解码为字符串类型
json_dict = json.loads(json_str) # 反序列化为字典类型
print(json_dict)
return render(request,'db_json.html')
# 补充:
# json.loads() 能够自动先解码再反序列化
# 所以:无需使用decode解码也可以
json_dict = json.loads(res)
总结:
ajax发送json格式数据需要注意点:
1.contentType参数指定成:application/json
2.数据是真正的json格式数据 # 前端需要序列化为json格式数据(JSON.stringify)
3.django后端不会帮你处理json格式数据需要你自己去request.body获取并处理
ajax发送文件数据
# ajax发送文件数据,需要借助于js内置方法
# 关键字: FormData
# 作用:可存储普通数据和文件数据,一并发送给后端
html前端页面:
<p>files<input type="file" name="username" class="form-control" id="d3"></p>
<button class="btn btn-info" id="d4">上传</button>
<script>
$('#d4').click(function (){
// 需要先利用FormData内置对象
let formDataObj = new FormData();
// 添加普通的键值对
formDataObj.append('username',$('#d1').val())
formDataObj.append('password',$('#d2').val())
// 添加文件对象
formDataObj.append('file',$('#d3')[0].files[0])
// 将对象基于ajax发送给后端
$.ajax({
url:'',
type:'post',
data:formDataObj, // 可直接将对象放在data后面
// ajax发送文件必须要指定的两个参数
contentType:false, // 不需要使用任何的编码,django后端能够自动识别fromdata对象
processData:false, // 告诉浏览器不要对数据进行任何的优化和处理
})
})
</script>
后端:
def db_files(request):
if request.is_ajax():
if request.method == 'POST':
print(request.POST)
print(request.FILES)
return render(request,'db_files.html')
总结:
# 1、需要利用内置对象FormData
let formDataObj = new FormData();
# 2、添加普通的键值对
formDataObj.append('username',$('#d1').val())
formDataObj.append('password',$('#d2').val())
# 3、添加文件对象
formDataObj.append('file',$('#d3')[0].files[0])
# 4、指定两个关键性的参数:
contentType:false, // 不需要使用任何的编码,django后端能够自动识别fromdata对象
processData:false, // 告诉浏览器不要对数据进行任何的优化和处理
# 5、结论:
django后端能够直接识别到formdata对象并且能够将内部的普通键值自动解析并封装到request.POST中 文件数据自动解析并封装到request.FILES中