You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅用Python标准库实现带文件POST请求时遇500错误求助

问题分析与解决

你的http.client代码返回500的核心原因是没有正确构造multipart/form-data格式的请求体,直接把文件内容作为请求body发送,这和requests生成的请求结构完全不符,Content-Length错误只是这个问题的衍生结果。

requests在处理files参数时,会自动生成符合multipart/form-data规范的请求体,包括边界分隔符的前后包裹、文件字段的描述信息(文件名、Content-Type等)、文件内容的正确嵌入。而你的http.client代码直接传了文件原始内容,服务器无法解析这种不符合规范的请求,因此返回500。

正确的http.client实现代码

import http.client
import ssl

httpHost = 'some host'
uri = 'some uri'
verb = 'POST'
boundary = 'TESTabc123'

# 读取文件内容
with open('C:/Users/abc/test.json', 'rb') as file:
    file_content = file.read()

# 构造multipart/form-data请求体,格式需严格遵循规范
body_parts = [
    f'--{boundary}'.encode('utf-8'),
    b'Content-Disposition: form-data; name="file"; filename="test.json"',
    b'Content-Type: application/json',
    b'',  # 空行分隔字段头部与内容
    file_content,
    f'--{boundary}--'.encode('utf-8'),
    b''  # 结尾空行
]
# 用\r\n拼接所有部分
body = b'\r\n'.join(body_parts)

# 计算整个请求体的总长度
content_length = len(body)

headers = {
    'Content-Type': f'multipart/form-data; boundary={boundary}',
    'Content-Length': str(content_length),
    'Accept': '*/*'
}

# 发送请求
conn = http.client.HTTPSConnection(httpHost, context=ssl._create_unverified_context())
conn.request(verb, uri, body=body, headers=headers)
response = conn.getresponse()
print(response.status)
print(response.read().decode('utf-8'))
conn.close()

关于urllib的SSL验证问题

如果用urllib.request实现,需手动传入不验证SSL的context,示例代码如下:

import urllib.request
import ssl

url = 'https://some host/some uri'
boundary = 'TESTabc123'

with open('C:/Users/abc/test.json', 'rb') as file:
    file_content = file.read()

# 构造multipart请求体,逻辑与http.client一致
body_parts = [
    f'--{boundary}'.encode('utf-8'),
    b'Content-Disposition: form-data; name="file"; filename="test.json"',
    b'Content-Type: application/json',
    b'',
    file_content,
    f'--{boundary}--'.encode('utf-8'),
    b''
]
body = b'\r\n'.join(body_parts)

headers = {
    'Content-Type': f'multipart/form-data; boundary={boundary}',
    'Content-Length': str(len(body)),
    'Accept': '*/*'
}

# 创建不验证SSL的上下文
context = ssl._create_unverified_context()
req = urllib.request.Request(url, data=body, headers=headers)

# 发送请求
with urllib.request.urlopen(req, context=context) as response:
    print(response.status)
    print(response.read().decode('utf-8'))

关键注意点

  • multipart请求体的每一部分必须用\r\n分隔,包括字段头部与内容间的空行、结尾的边界分隔符。
  • 请求头中的boundary必须和请求体中使用的完全一致。
  • Content-Length必须是整个请求体(含所有boundary、字段描述、文件内容、空行)的总长度,而非单纯的文件内容长度。

内容的提问来源于stack exchange,提问作者JayEstrera

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 19:15:18