python3使用requests上传文件,content-type踩的坑

上篇推送的时候代码格式在手机里展示不全,本次修改了各式问题

通常提交普通表单时,requestspost方法可以指定headers,所以我在使用requests模拟上传文件行为时,直接按照下面的方式写了:

然后服务器就报出了找不到分隔符Invalid multipart/form-data: multipart boundary not found

网上找了半天也没找到为什么,倒是大家给的示例比我写的少用了一个headers,尝试着调整了一下,去掉headers参数就可以上传了,我怀疑时requests内部会检查用户是否已经定义了headers,如果定义了,则直接使用,否则requests根据其他参数自动给生成headers。

所以我想,如果是这样,那我再headers里把需要的内容都写上,应该也是可以的,上面提示未找到boundary,那么我自己写上boundary(http协议允许用户自定义boundary):

定义了boundary,但是服务器却报出没有final boundary,我们知道,post编码时,发送前会用boundary分割不同字段,最后以前后都有--的boundary结束。所以,出现找不到final boundary应该就是自定义的boundary没有起到作用,去看源代码吧。

翻出requests源代码,在models.py文件里,函数就是对post字段进行编码的,对于上传文件来讲,content_type来自函数;最终通过生成boundary,拼接出模块内的content_type。

如果用户没有自定义content-type,那么就使用模块内自己随机生成的boundary。但是返回到prepare_body里,最后会判断用户是否定义了content-type,如果定义了则使用用户定义好的,相关代码如下:

所以,从这里可以看出,无论用户怎么定义content-type,实际用到的boundary还是模块自己生成的,而且一旦用户自定义了content-type,最终post请求的headers里携带的boundary跟实际编码用到的boundary就会不一致,导致服务器端无法解析。

总结为一句话:使用requests的post方法上传文件时,不能自定义headers里的content-type。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180715G0AUL900?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券