如何发送 JSON 作为多部分 POST-请求的一部分
How to send JSON as part of multipart POST-request
我有以下 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--
我尝试发送 POST-请求 requests
:
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()
但它 returns 状态 400
具有以下评论:
Required request part \'json\' is not present.
The request sent by the client was syntactically incorrect.
请指出我的错误。我应该更改什么才能使其正常工作?
您正在自己设置 header,包括边界。不要这样做; requests
为您生成一个边界并将其设置在 header 中,但是如果您 已经 设置了 header 那么生成的负载和 header 将不匹配。干脆丢下你 headers:
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
路径的基本名称)。
有关 multi-part POST 请求的详细信息,请参阅 advanced section of the documentation。
万一有人搜索准备好使用方法将 python 字典转换为 multipart-form 数据结构 here 是进行此类转换的简单要点示例:
{"some": ["balls", "toys"], "field": "value", "nested": {"objects": "here"}}
->
{"some[0]": "balls", "some[1]": "toys", "field": "value", "nested[objects]": "here"}
要发送一些数据,您可能需要使用此要点中的 multipartify
方法,如下所示:
import requests # library for making requests
payload = {
"person": {"name": "John", "age": "31"},
"pets": ["Dog", "Parrot"],
"special_mark": 42,
} # Example payload
requests.post("https://example.com/", files=multipartify(payload))
要将相同的数据与任何文件一起发送(如 OP 所愿),您可以像这样简单地添加它:
converted_data = multipartify(payload)
converted_data["attachment[0]"] = ("file.png", b'binary-file', "image/png")
requests.post("https://example.com/", files=converted_data)
请注意,attachment
是由服务器端点定义的名称,可能会有所不同。 attachment[0]
表示它是您请求的第一个文件 - 这也应该由 API 文档定义。
我有以下 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--
我尝试发送 POST-请求 requests
:
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()
但它 returns 状态 400
具有以下评论:
Required request part \'json\' is not present.
The request sent by the client was syntactically incorrect.
请指出我的错误。我应该更改什么才能使其正常工作?
您正在自己设置 header,包括边界。不要这样做; requests
为您生成一个边界并将其设置在 header 中,但是如果您 已经 设置了 header 那么生成的负载和 header 将不匹配。干脆丢下你 headers:
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
路径的基本名称)。
有关 multi-part POST 请求的详细信息,请参阅 advanced section of the documentation。
万一有人搜索准备好使用方法将 python 字典转换为 multipart-form 数据结构 here 是进行此类转换的简单要点示例:
{"some": ["balls", "toys"], "field": "value", "nested": {"objects": "here"}}
->
{"some[0]": "balls", "some[1]": "toys", "field": "value", "nested[objects]": "here"}
要发送一些数据,您可能需要使用此要点中的 multipartify
方法,如下所示:
import requests # library for making requests
payload = {
"person": {"name": "John", "age": "31"},
"pets": ["Dog", "Parrot"],
"special_mark": 42,
} # Example payload
requests.post("https://example.com/", files=multipartify(payload))
要将相同的数据与任何文件一起发送(如 OP 所愿),您可以像这样简单地添加它:
converted_data = multipartify(payload)
converted_data["attachment[0]"] = ("file.png", b'binary-file', "image/png")
requests.post("https://example.com/", files=converted_data)
请注意,attachment
是由服务器端点定义的名称,可能会有所不同。 attachment[0]
表示它是您请求的第一个文件 - 这也应该由 API 文档定义。