故障表现
本地用 open 读文件再传给 files,接口返回上传成功,但后台看文件大小始终是 0,换成表单工具上传就正常。
问题出在哪
files 参数传的是已读过的文件对象,指针停在末尾,requests 从当前位置读到的是空内容。判断时先分清是 requests 文件上传 本身的配置问题,还是上游调用、运行环境带进来的差异;前者改配置就能收口,后者要沿着请求链路一层层往上找,处理顺序不能颠倒。先在出问题的机器上复现一次,把报错原文和发生时间记下来,再对着日志定位。
按这个顺序处理
- 确认打开文件时没有先 read 过
- 传文件对象而不是 read 后的字节串
- 需要改文件名或 MIME 时用三元组形式
对应的命令或配置片段如下,可直接复制:
with open('a.pdf', 'rb') as f:
r = requests.post(url, files={'file': ('a.pdf', f, 'application/pdf')}, timeout=30)
print(r.status_code, r.text[:200])
改完只在一台机器上验证不够,至少从外网和移动网络各试一次,才能确认不是本地缓存造成的假象。不要一次改多个参数,每次只动一处并记录下来,否则现象变了也说不清是哪个改动起的作用。
怎么确认改好了
上传后对比服务端返回的文件大小与本地一致,再下载回来能正常打开,才算通过。