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

And*_*son 5 python json multipartform-data http-post python-requests

我有以下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--
Run Code Online (Sandbox Code Playgroud)

我尝试发送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()
Run Code Online (Sandbox Code Playgroud)

但它返回状态,400并带有以下注释:

Required request part \'json\' is not present.
The request sent by the client was syntactically incorrect.
Run Code Online (Sandbox Code Playgroud)

请指出我的错误.我应该改变什么来使它工作?

Mar*_*ers 10

您自己设置标题,包括边界.不要这样做; 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)
Run Code Online (Sandbox Code Playgroud)

请注意,我还为file部分提供了文件名(file路径的基本名称).

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