用Curl如何发布multipart/form-data数据,以及如何在Flask请求中读取multipart/form-data

9

我尝试通过CURL发布multipart/form-data,其中包含:

  • JSON对象
  • 流对象pdf和jpeg文件
  curl -i -X POST -H  
"Authorization":"eyJhbGciOiJIUzI1NiIsImV4cCI6MTQyNjcwNTY4NiwiaWF0IjoxNDI2NzAyMDg2fQ.eyJpZCI6MTc3fQ.yBwLFez2RnxTojLniL8YLItWVvBb90HF_yfhcsyg3lY" -H    

"Content-Type:application/multipart/form-data" -d '{"user data":  {"preferred_city":"Newyork","within_radious":"5"}}' --data-binary   

"uploaded_documents":@mydocument.pdf http://127.0.0.1:5000/api/city

现在,我需要在 Flask 请求对象中读取这个多部分数据。我已经尝试过:
request.data

它确实打印了数据,但我不确定如何读取流对象并将文件存储到磁盘中。

你能试一下 request.form 吗? - itzMEonTV
request.form字典长度为零,表单中没有数据。 - Satish
这是在request.data中的内容 ---- str: {"userdata":{"preferred_city":"Newyork","within_radious":"5"}}&uploaded_documents:@mydocument.pdf - Satish
1个回答

16

你的curl命令存在几个问题,这些问题都可能导致问题:

  1. application/multipart/form-data 不是一个有效的 MIME 类型,因此 Content-Type 是无效的。对于文件上传,内容类型通常为 multipart/form-data。另外,你不需要指定内容类型,curl 会根据参数自动确定。
  2. 使用 -F 而不是 -d 会导致curl生成并发布一个带有有效边界的 multipart/form-data 表单。
  3. 每个表单字段都应指定名称。

将它们整合到一起,得到以下curl命令:

curl -i -H "Authorization":"eyJhbGciOiJIUzI1NiIsImV4cCI6MTQyNjcwNTY4NiwiaWF0IjoxNDI2NzAyMDg2fQ.eyJpZCI6MTc3fQ.yBwLFez2RnxTojLniL8YLItWVvBb90HF_yfhcsyg3lY" \
    -F user_data='{"user data": {"preferred_city":"Newyork","within_radious":"5"}}' \
    -F uploaded_documents=@mydocument.pdf \
    http://127.0.0.1:5000/api/city
您可以针对每个部分指定内容类型,如果您不喜欢curl选择的类型(文件将为application/octet-stream):
curl -i -H "Authorization":"eyJhbGciOiJIUzI1NiIsImV4cCI6MTQyNjcwNTY4NiwiaWF0IjoxNDI2NzAyMDg2fQ.eyJpZCI6MTc3fQ.yBwLFez2RnxTojLniL8YLItWVvBb90HF_yfhcsyg3lY" \
    -F 'user_data={"user data": {"preferred_city":"Newyork","within_radious":"5"}};type=application/json' \
    -F 'uploaded_documents=@mydocument.pdf;type=application/pdf' \
    http://127.0.0.1:5000/api/city
最后的命令将生成如下HTTP请求:
POST /api/city HTTP/1.1
User-Agent: curl/7.32.0
Host: 127.0.0.1:5000
Accept: */*
Authorization:eyJhbGciOiJIUzI1NiIsImV4cCI6MTQyNjcwNTY4NiwiaWF0IjoxNDI2NzAyMDg2fQ.eyJpZCI6MTc3fQ.yBwLFez2RnxTojLniL8YLItWVvBb90HF_yfhcsyg3lY
Content-Length: 496
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------1ab997efff76fe66
--------------------------1ab997efff76fe66 Content-Disposition: form-data; name="user_data" Content-Type: application/json
{"user data": {"preferred_city":"Newyork","within_radious":"5"}} --------------------------1ab997efff76fe66 Content-Disposition: form-data; name="uploaded_documents"; filename="mydocument.pdf" Content-Type: application/pdf
这是 mydocument.pdf 文件。 它应该是一个 PDF 文件,但使用它进行测试更加容易。
--------------------------1ab997efff76fe66--
然后在 Flask 中,您可以使用 request.form 访问表单数据,例如 request.form['user_data']。由于它是一个 JSON 字符串,您可以使用 json.loads(request.form['user_data']) 加载它。
上传的文件可以通过使用 request.file 访问,如 Flask 文档中所述:这里这里

谢谢 mhawke.. 它甚至可以同时处理多个 application/octet-stream 文件,非常完美。 - Satish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接