在Django中获取请求正文作为字符串

zel*_*nix 21 python django

我正在向一个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")
Run Code Online (Sandbox Code Playgroud)

但是,这会产生错误the JSON object must be str, not 'bytes'.

如何应用正确的编码来检索请求的正文作为字符串?

Ala*_*air 42

请求主体request.body是一个字节字符串.在Python 3中,json.loads()只接受一个unicode字符串,因此request.body在传递给它之前必须进行解码json.loads().

body_unicode = request.body.decode('utf-8')
body_data = json.loads(body_unicode)
Run Code Online (Sandbox Code Playgroud)

在Python 2中,json.loads将接受unicode字符串或字节sting,因此解码步骤不是必需的.

解码字符串时,我认为你可以安全地假设'utf-8' - 我找不到一个明确的来源,但是请参阅下面jQuery文档中的引用:

注意:W3C XMLHttpRequest规范规定字符集始终为UTF-8; 指定另一个字符集不会强制浏览器更改编码.

在Python 3.6中,json.loads()接受字节或字节数组.因此,您不需要解码request.body(假设它以UTF-8编码).

  • `utf-8`也是`decode()`方法的第一个参数的默认值(检查`help(bytes.decode)`) (2认同)
  • 在Python> = 3.6中,`json.loads`也可以接受`bytes`参数,并假设它以UTF-8,UTF-16或UTF-32编码.https://docs.python.org/3/library/json.html#json.loads (2认同)