我正在向一个Django服务器发送一个带有JSON主体的POST请求(相当标准)。在服务器上,我需要使用json.loads()
解码它。
问题是我如何以字符串格式获取请求的正文?
我目前有以下代码:
body_data = {}
if request.META.get('CONTENT_TYPE', '').lower() == 'application/json' and len(request.body) > 0:
try:
body_data = json.loads(request.body)
except Exception as e:
return HttpResponseBadRequest(json.dumps({'error': 'Invalid request: {0}'.format(str(e))}), content_type="application/json")
但是,这会产生错误the JSON object must be str, not 'bytes'
。
如何在应用正确的编码的情况下以字符串形式检索请求正文?
答案 0 :(得分:37)
请求正文request.body
是一个字节字符串。在Python 3中,json.loads()
只接受unicode字符串,因此您必须先解码request.body
,然后再将其传递给json.loads()
。
body_unicode = request.body.decode('utf-8')
body_data = json.loads(body_unicode)
在Python 2中,json.loads
将接受unicode字符串或字节sting,因此不需要解码步骤。
解码字符串时,我认为您可以安全地假设'utf-8' - 我无法找到明确的来源,但请参阅jQuery docs下面的引文:
注意:W3C XMLHttpRequest规范规定charset始终为UTF-8;指定另一个字符集不会强制浏览器更改编码。
在Python 3.6中,json.loads()
accepts bytes or bytearrays。因此,您不需要解码request.body
(假设它以UTF-8编码)。
答案 1 :(得分:1)
我相信您收到此请求的另一端在发送请求之前不会将数据转换为JSON。您必须在发送之前将数据转换为JSON,或者只是尝试在您的视图中访问request.body。
答案 2 :(得分:0)
如果您的目标是获得使用JSON发送到服务器的数据的字典,请避免自己解码正文的麻烦,并使用django已经提供的request.POST
类似于字典的对象开箱即用。
因此,假设您将此发布到服务器:
{ 'foo': 'bar' }
然后使用以下方法
def my_handler(request):
foo = request.POST['foo']
print(foo)
将bar
打印到控制台