[英]How to send JSON as part of multipart POST-request
I have following POST-request form (simplified):我有以下 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--
I try to send POST-request with requests
:我尝试发送带有requests
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()
but it returns status 400
with following comment:但它返回状态400
并带有以下注释:
Required request part \'json\' is not present.
The request sent by the client was syntactically incorrect.
Please point on my mistake.请指出我的错误。 What should I change to make it work?我应该改变什么才能使它工作?
You are setting the header yourself, including a boundary.您自己设置标题,包括边界。 Don't do this;不要这样做; requests
generates a boundary for you and sets it in the header, but if you already set the header then the resulting payload and the header will not match. requests
为您生成一个边界并将其设置在标头中,但如果您已经设置了标头,则生成的有效负载和标头将不匹配。 Just drop you headers altogether:只需完全删除标题:
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)
Note that I also gave the file
part a filename (the base name of the file
path`).请注意,我还为file
部分指定了文件名( file
路径的基本名称)。
For more information on multi-part POST requests, see the advanced section of the documentation .有关多部分 POST 请求的更多信息,请参阅文档的高级部分。
In case if someone searches ready to use method to transform python dicts to multipart-form data structures here is a simple gist example to do such transformation:如果有人搜索准备使用的方法将 python dicts 转换为多部分形式的数据结构, 这里是一个简单的 gist 示例来进行这种转换:
{"some": ["balls", "toys"], "field": "value", "nested": {"objects": "here"}}
->
{"some[0]": "balls", "some[1]": "toys", "field": "value", "nested[objects]": "here"}
To send some data you may want to use the multipartify
method from this gist like this:要发送一些数据,您可能需要使用此 gist 中的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))
To send same data along with any file (as OP wanted) you may simply add it like this:要与任何文件一起发送相同的数据(如 OP 所需),您可以简单地添加如下:
converted_data = multipartify(payload)
converted_data["attachment[0]"] = ("file.png", b'binary-file', "image/png")
requests.post("https://example.com/", files=converted_data)
Note, that attachment
is a name defined by server endpoint and may vary.请注意, attachment
是由服务器端点定义的名称,可能会有所不同。 Also attachment[0]
indicates that it is first file in you request - this is also should be defined by API documentation.此外, attachment[0]
表示它是您请求中的第一个文件 - 这也应该由 API 文档定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.