0、干货先写在前
1、前端传值的数据必须使用JSON.stringify()传化
2、后端,通过request.body接收数据,直接使用json.loads解析,解析前,先decode一下:receive_data = json.loads(request.body.decode())。如果使用simplejson.loads(request.body),就不用decode()
下面是这个问题产生及解决的过程,还有一些可能的应用场景。
1、传统方式解析表单数据
之前用Django后台接收数据的时候,一直采用的是表单的形式,通过Ajax传值的时候也是一样,直接通过键值对儿将值传递给后台,前端代码类似这样:
$.post("/login/", { "user":"threedog", "password":"123456" }, function (res) { console.log(res) });
在后台采用`request.POST`进行数据接收:
class Login(View): def get(self,request): return render(request,'login.html') def post(self,request): print(request.POST) print("user :",end='') print(request.POST.get('user',None)) print("password :",end='') print(request.POST.get('password',None)) return HttpResponse('OK')
后台接收到的是一个QueryDict,打印如下:
可以看到这里的数据是按照Json的格式传递的,后台也完美地进行解析,但是,如果前端传递的数据为嵌套的Json,这种写法就开始出现问题!
2、解析嵌套的Json数据
前端代码修改如下:
$.post("/login/", { "user":{ 'name':'threedog', 'age':18, 'sex':'男' }, "password":"123456" }, function (res) { console.log(res) });
这个时候后台收到的东西就有意思了:
password取值正常,但是user没能拿到值,而QueryDict的打印我们发现,原本是嵌套的字典,现在全部由两个键名合并成了新的键诸如:'user[sex]','user[age]'。这样的键到了后台是没办法按照普通字典或者json来进行解析的。
上网查,说是要使用request.raw_post_data代替request.POST就可以,然而很遗憾,报错再查之下发现,raw_post_data在Django1.4版本之后被取消,我使用的是Django1.11。再往下查,知道了要使用request.body,还要通过simplejson来解析。
但是request.body的解析仍然不顺利,前端不变,后台直接打印request.body的结果如下:
一个包含了键值对儿的二进制字符串,这个时候按网上的办法使用simplejson.loads()解析会报错:simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)。不用在这个上面纠结了,simplejson直接解析不了这个body。
后来灵感突发,发现前端在给出的数据原本就是JS中的object,并不是json的字符串,所以把前段的数据使用JSON.stringify()进行转换后,打印request.body以及通过simplejson.load()解析发现了令人惊喜的输出:
到了这一步就基本不用说啥了,完整接收了前端的json字符串并解析,这里如果不想安装第三方库simplejson的话,使用python自带的json模块也是可以解析的,只是在解析时需要将request.body进行一次decode()即可。完整代码如下
前端:
$.post("/login", JSON.stringify({ "user":{ 'name':'threedog', 'age':18, 'sex':'男' }, "password":"123456" }), function (res) { console.log(res) });
后台:
class Login(View): def get(self,request): return render(request,'login.html') def post(self,request): print(request.body) receive_data = simplejson.loads(request.body) print(receive_data) receive_data = json.loads(request.body.decode()) print(receive_data) return HttpResponse('OK')
程序输出:
之前主要是因为写前端给数据的时候没有使用JSON.stringify()进行处理。导致后台无论什么方法解析都是一团糟。
3、简述应用场景
这个应用场景非常常见,除了我刚才提到的,前端给后台的,是嵌套的json数据的情况。还有微信小程序给后台数据,也需要JSON.stringify()处理给json,还有安卓,IOS app访问网站后台提交数据,都需要这种方式传值和解析。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
更新日志
- 小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE]
- 群星《欢迎来到我身边 电影原声专辑》[320K/MP3][105.02MB]
- 群星《欢迎来到我身边 电影原声专辑》[FLAC/分轨][480.9MB]
- 雷婷《梦里蓝天HQⅡ》 2023头版限量编号低速原抓[WAV+CUE][463M]
- 群星《2024好听新歌42》AI调整音效【WAV分轨】
- 王思雨-《思念陪着鸿雁飞》WAV
- 王思雨《喜马拉雅HQ》头版限量编号[WAV+CUE]
- 李健《无时无刻》[WAV+CUE][590M]
- 陈奕迅《酝酿》[WAV分轨][502M]
- 卓依婷《化蝶》2CD[WAV+CUE][1.1G]
- 群星《吉他王(黑胶CD)》[WAV+CUE]
- 齐秦《穿乐(穿越)》[WAV+CUE]
- 发烧珍品《数位CD音响测试-动向效果(九)》【WAV+CUE】
- 邝美云《邝美云精装歌集》[DSF][1.6G]
- 吕方《爱一回伤一回》[WAV+CUE][454M]