正确写法是用 files 参数传 XML 文件,如 files={'file': ('config.xml', f, 'application/xml')};不能用 data 或 json,否则服务端收不到原始 XML 内容,且 data 接收文件对象会转为字符串而非字节流。
requests.post 上

直接用 files 参数传 XML 文件,不是用 data 或 json。否则服务端收不到原始 XML 内容,或被自动序列化成字符串、丢失根标签和声明。
为什么不能用 data=open(...)?
常见错误是把文件对象塞进 data,比如 data=open('a.xml', 'rb') —— 这会让 requests 把文件对象转成字符串(如 <_io.bufferedreader name="a.xml">),根本不是 XML 内容。
-
data适合传 raw 字节或字符串,不带文件名、无Content-Disposition头 -
files才会构造 multipart/form-data,带上文件名和类型,服务端才能当「上传文件」处理 - XML 文件没有固定 MIME 类型,但建议显式设为
application/xml或text/xml
完整上传示例(含文件名与类型)
关键点:用 files 构造二元组 (field_name, (filename, file_obj, content_type)),其中 field_name 必须和服务端约定一致(比如后端 expecting file 字段)。
import requests
with open('config.xml', 'rb') as f:
files = {
'file': ('config.xml', f, 'application/xml')
}
response = requests.post(
'https://api.example.com/upload',
files=files
)
print(response.status_code)
print(response.text)
容易踩的坑
XML 文件开头有 BOM 或编码不匹配时,服务端解析可能失败,但错误常不明确。
- 确保用
'rb'模式打开,避免文本模式自动换行符转换 - 如果 XML 声明是
,但文件实际是 UTF-8 with BOM,部分服务端会报「invalid token」——用open(..., 'rb').read().lstrip(b'\xef\xbb\xbf')去 BOM - 某些 API 要求 XML 必须放在 form 的特定字段(如
upload_file),而不是通用file,字段名错就 400 - 不用
headers={'Content-Type': 'multipart/form-data'}—— requests 会自动生成带 boundary 的正确头,手动设反而破坏 multipart 结构








