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

Python中如何在带参数的POST请求中同时上传文件?

嘿,我来帮你搞定这个文件上传的问题!首先得指出你原来代码里的一个小矛盾:你设置的Content-type是application/x-www-form-urlencoded,但Accept是multipart/form-data——要上传文件的话,请求体必须用multipart/form-data格式,而且Content-type头得包含一个用来分隔表单内容的边界字符串(boundary)。

下面是修改后的完整实现,我会一步步给你解释关键部分:

实现文件+表单参数的POST请求

首先我们需要构造符合multipart/form-data格式的请求体,把普通参数(par1、par2)和文件内容一起打包进去:

import httplib
import random
import string

# 生成随机的boundary字符串,用来分隔表单中的不同部分(避免内容冲突)
boundary = '----' + ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(16))

def build_multipart_formdata(fields, files):
    """构造multipart/form-data格式的请求体"""
    body_parts = []
    
    # 添加普通表单参数(par1、par2这类)
    for field_name, field_value in fields.items():
        body_parts.append(f'--{boundary}')
        body_parts.append(f'Content-Disposition: form-data; name="{field_name}"')
        body_parts.append('')  # 空行分隔头和内容
        body_parts.append(str(field_value))
    
    # 添加文件内容
    for file_field_name, file_info in files.items():
        filename, file_content, content_type = file_info
        body_parts.append(f'--{boundary}')
        body_parts.append(f'Content-Disposition: form-data; name="{file_field_name}"; filename="{filename}"')
        body_parts.append(f'Content-Type: {content_type}')
        body_parts.append('')  # 空行分隔头和文件内容
        body_parts.append(file_content)
    
    # 结尾的边界标记
    body_parts.append(f'--{boundary}--')
    body_parts.append('')
    
    # 用\r\n拼接所有部分(multipart格式要求的换行符)
    return '\r\n'.join(body_parts)

# ---------------------- 替换成你自己的参数和文件信息 ----------------------
# 普通表单参数(par1、par2)
form_fields = {'par1': '1', 'par2': '2'}

# 文件信息:这里需要你替换成实际的文件路径、服务器接收文件的字段名、文件类型
file_field_name = 'upload_file'  # 服务器端用来接收文件的字段名,比如后端用request.files['upload_file']获取
target_filename = 'example.txt'
with open(target_filename, 'rb') as f:
    file_content = f.read()  # 二进制读取文件,避免编码问题
file_info = (target_filename, file_content, 'text/plain')  # 非文本文件要改Content-Type,比如图片用image/jpeg

# 构造请求体
request_body = build_multipart_formdata(form_fields, {file_field_name: file_info})

# 设置正确的请求头
headers = {
    'Content-Type': f'multipart/form-data; boundary={boundary}'
    # 如果服务器有特殊的Accept要求,再加上对应的Accept头即可
}

# 发送请求(URL里的par3、par4保持不变)
conn = httplib.HTTPConnection("somedomain.com")
conn.request(
    method="POST",
    url="/cportal/public/api/edit?par3=3&par4=4",
    body=request_body,
    headers=headers
)

# 可选:获取并处理响应
response = conn.getresponse()
print(f"响应状态:{response.status} {response.reason}")
print("响应内容:", response.read())
conn.close()

关键要点说明

  • Boundary字符串:必须是一个不会出现在文件内容或表单参数里的随机字符串,用来告诉服务器哪里是一个字段的结束、下一个字段的开始。
  • 请求头调整:原来的application/x-www-form-urlencoded要替换成multipart/form-data; boundary=xxx,这是服务器识别文件上传请求的关键。
  • 文件读取:用二进制模式rb读取文件,确保非文本文件(比如图片、PDF)的内容不会被损坏。
  • Content-Type适配:不同类型的文件要设置对应的Content-Type,比如图片用image/png,PDF用application/pdf,如果不确定可以用application/octet-stream(通用二进制类型)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:01:48