如何将 JSON 作为多部分 POST 请求的一部分发送

新手上路,请多包涵

我有以下 POST 请求表单(已简化):

 POST /target_page HTTP/1.1
Host: server_IP:8080
Content-Type: multipart/form-data; boundary=AaaBbbCcc

--AaaBbbCcc
Content-Disposition: form-data; name="json"
Content-Type: application/json

{ "param_1": "value_1", "param_2": "value_2"}

--AaaBbbCcc
Content-Disposition: form-data; name="file"; filename="..."
Content-Type: application/octet-stream

<..file data..>
--AaaBbbCcc--

我尝试使用 requests 发送 POST 请求:

 import requests
import json

file = "C:\\Path\\To\\File\\file.zip"
url = 'http://server_IP:8080/target_page'

def send_request():
    headers = {'Content-type': 'multipart/form-data; boundary=AaaBbbCcc'}

    payload = { "param_1": "value_1", "param_2": "value_2"}

    r = requests.post(url, files={'json': (None, json.dumps(payload), 'application/json'), 'file': (open(file, 'rb'), 'application/octet-stream')}, headers=headers)

    print(r.content)

if __name__ == '__main__':
    send_request()

但它返回状态 400 并附有以下评论:

 Required request part \'json\' is not present.
The request sent by the client was syntactically incorrect.

请指出我的错误。我应该改变什么才能让它发挥作用?

原文由 Andersson 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 453
2 个回答

您正在自己设置标题,包括边界。不要这样做; requests 为您生成边界并将其设置在标头中,但如果您 已经 设置了标头,则生成的有效负载和标头将不匹配。完全放弃标题:

 def send_request():
    payload = {"param_1": "value_1", "param_2": "value_2"}
    files = {
         'json': (None, json.dumps(payload), 'application/json'),
         'file': (os.path.basename(file), open(file, 'rb'), 'application/octet-stream')
    }

    r = requests.post(url, files=files)
    print(r.content)

请注意,我还为 file 部分提供了一个文件名( file 的基本名称)。

有关多部分 POST 请求的更多信息,请参阅 文档的高级部分

原文由 Martijn Pieters 发布,翻译遵循 CC BY-SA 4.0 许可协议

我完全同意@Martijn 的回答……但你也可以这样做:

1.发送请求

import json
import requests

cover   = 'superneat.jpg'
payload = {'title': 'The 100 (2014)', 'episodes': json.dumps(_episodes)}
files   = [
            ('json', ('payload.json', json.dumps(payload), 'application/json')),
            ('cover', (cover, open(cover, 'rb')))
          ]
r       = requests.post("https://superneatech.com/store/series", files=files)

print(r.text)

2.接收请求

您将收到作为文件的 JSON 数据,获取内容并继续…

参考: 在这里查看

原文由 Superneat 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题