在 Django 中获取请求正文作为字符串
Posted
技术标签:
【中文标题】在 Django 中获取请求正文作为字符串【英文标题】:Get request body as string in Django 【发布时间】:2015-06-13 09:03:21 【问题描述】:我正在向 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'
。
如何在应用正确编码的情况下以字符串形式检索请求正文?
【问题讨论】:
request.read()
能完成这项工作吗?
@dhke,不,它给出了相同的结果,这实际上让我感到惊讶。 request.body.decode('utf-8')
似乎有效,但我不确定这是否是最好的方法?
【参考方案1】:
请求正文request.body
是一个字节字符串。在 Python 3.0 到 3.5.x 中,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 字符串或字节字符串,因此不需要解码步骤。
在解码字符串时,我认为您可以安全地假设 'utf-8' - 我找不到确切的来源,但请参阅下面来自 jQuery docs 的引用:
注意:W3C XMLHttpRequest 规范规定字符集始终为 UTF-8;指定另一个字符集不会强制浏览器更改编码。
在 Python 3.6 中,json.loads()
accepts bytes or bytearrays。因此,您不需要解码 request.body
(假设它以 UTF-8 编码)。
【讨论】:
utf-8
也是decode()
方法的第一个参数的默认值(检查help(bytes.decode)
)
在 Python >= 3.6 中,json.loads
也可以接受 bytes
参数,并且假定它以 UTF-8、UTF-16 或 UTF-32 编码。 docs.python.org/3/library/json.html#json.loads
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfb in position 9: invalid start byte python 3 7 7
@CoffeeinTime 该错误表明请求正文不是有效的 utf-8。如果您控制它,请修复客户端,如果您不控制,请添加适当的错误处理。【参考方案2】:
如果您的目标是使用 JSON 获得刚刚发送到服务器的数据的字典,请省去自己解码正文的麻烦,并使用 django 已经提供的request.POST
类字典对象 -开箱即用。
所以假设你 POST 到服务器:
'foo': 'bar'
那么下面的方法
def my_handler(request):
foo = request.POST['foo']
print(foo)
将bar
打印到控制台
【讨论】:
好吧,我在阅读 django 时遇到了这个问题,意识到有一个更简单的解决方案,所以我发布了它。那是一件坏事?这是一个较老的问题有关系吗?恕我直言,它仍然相关 谢谢,这正是我所需要的!发帖总比不发帖好,永远不知道对谁有帮助。 这个答案不正确。request.POST
仅在请求正文是表单编码的情况下才有效。如果数据是 json 编码的,它将不起作用。【参考方案3】:
我相信您收到此请求的另一端在发送请求之前不会将数据转换为 JSON。您必须在发送之前将数据转换为 JSON,或者只是尝试在您的视图中访问 request.body。
【讨论】:
感谢您的回答。我认为它是有效的 json - 如果我使用request.body.decode('utf-8')
那么它可以工作。你会说有理由不这样做吗?以上是关于在 Django 中获取请求正文作为字符串的主要内容,如果未能解决你的问题,请参考以下文章
Alamofire POST 请求,正文中有一个简单的字符串作为参数,标头仍然显示缺少的参数值
django 获取request请求对象及response响应对象中的各种属性值
如何在 Spring REST 控制器中获取原始 JSON 正文?