python urllib3 multipart/form-data 的坑

################################3.上传文件时带了个header与urllib3.request.py不兼容

传header的Content-Type时,应区分大小写

def request_encode_body(self, method, url, fields=None, headers=None,

encode_multipart=True, multipart_boundary=None,

**urlopen_kw):

...

extra_kw['body'] = body

extra_kw['headers'] = {'Content-Type': content_type}#这里header中必须是Content-Type,如果用户传来的header中已经有了'content-type', 则最终实际会出现2个这个重复值, 访问接口时会报错

extra_kw['headers'].update(headers)

...

#实际使用的header为:

#'content-type': 'multipart/form-data; boundary=----WebKitFormBoundary0b1047518e88296',

#'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundary0b1047518e88296'

################################2.上传文件后缀总是为null的问题解决

上传文件后缀总是为null的问题解决

注意这里的example.jpeg只能是文件名, 不能是带路径的, 若写成"\\image\\example.jpeg"上传的文件后缀就成null了.

fields={

'text': ('None', "upload a string",'None'),

'file': ('example.jpeg',file_data,"image/jpeg"),

}

##################################1

在一个项目中用到python urllib3上传文件

urllib3.disable_warnings()

http = urllib3.PoolManager()

with open('example.jpeg','rb') as fp:

file_data = fp.read()

r = http.request(

'POST',

'http://httpbin.org/post',

headers = {'Content-Type':"multipart/form-data"},

fields={

'text': ('None', "upload a string",'None'),

'file': ('example.jpeg',file_data,"image/jpeg"),

})

结果上传错误, 试着打印出urllib3组成的post body, 打开D:\python27\Lib\site-packages\urllib3\request.py的request_encode_body函数, 在return 前面加上print extra_kw, 打印出的body结果如下:

我使用postman发送该接口上传文件都是对的:

点击Send下面一行的红色 Code,HTTP显示的是:

发现这里的boundary与python中的urllib3不一样. 原来urllib3 是post form-data时, 没有传multipart_boundary该参数会自动生成:D:\python27\Lib\site-packages\urllib3\filepost.py

def encode_multipart_formdata(fields, boundary=None):

...

if boundary is None:

boundary = choose_boundary()

def choose_boundary():

"""

Our embarrassingly-simple replacement for mimetools.choose_boundary.

"""

return uuid4().hex#生成的是32为的唯一码

试着在python中修改为以WebKitFormBoundary开头的试着再执行, 还是报错, 用同样的方法, 查找到headers的Content-Type没有带上boundary,在header中明明带了Content-Type:multipart/form-data, 调试发现:header中传了Content-Type后, urllib3生成的带boundary的Content-Type会被传进来的覆盖掉,如下:

D:\python27\Lib\site-packages\urllib3\request.py

def request_encode_body(self, method, url, fields=None, headers=None,

encode_multipart=True, multipart_boundary=None,

**urlopen_kw):

if headers is None:

headers = self.headers

extra_kw = {'headers': {}}

if fields:

if 'body' in urlopen_kw:

raise TypeError(

"request got values for both 'fields' and 'body', can only specify one.")

if encode_multipart:

body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary)#产生了新的content-type

else:

body, content_type = urlencode(fields), 'application/x-www-form-urlencoded'

extra_kw['body'] = body

extra_kw['headers'] = {'Content-Type': content_type}#也将产生的新的content-type加到headers中了

extra_kw['headers'].update(headers)#一更新headers又还原成传进来的headers了

extra_kw.update(urlopen_kw)

return self.urlopen(method, url, **extra_kw)

总结可行方案:

1.http.request传的参数中带fields时,带上特定的boundary(以WebKitFormBoundary开头的, 原因未知, 知道的朋友可以留言告知),headers中不要带Content-Type;

2.http.request传的参数要带上headers的话,格式应该是:Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

最终的代码修改:

urllib3.disable_warnings()

http = urllib3.PoolManager()

with open('example.jpeg','rb') as fp:

file_data = fp.read()

boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'

#方案1

r = http.request(

'POST',

'http://httpbin.org/post',

headers = {},

multipart_boundary = boundary,

fields={

'text': ('None', "upload a string",'None'),

'file': ('example.jpeg',file_data,"image/jpeg"),

})

#方案2

r = http.request(

'POST',

'http://httpbin.org/post',

headers = {'Content-Type':"multipart/form-data;%s"%boundary},

multipart_boundary = boundary,

fields={

'text': ('None', "upload a string",'None'),

'file': ('example.jpeg',file_data,"image/jpeg"),

})

python urllib3 上传大文件,python urllib3 multipart/form-data 的坑相关推荐

  1. python requests上传大文件_pythonrequestspost大文件和获取进度条

    问题: python requests post 大文件和获取进度条 描述: 准备用HTTP 在局域网内 上传一些文件,文件一般都在1G左右r = requests.post('****', data ...

  2. python urllib3 上传大文件_python urllib和urllib3包使用

    urllib包 urllib是一个包含几个模块来处理请求的库.分别是: urllib.request 发送http请求 urllib.error 处理请求过程中,出现的异常. urllib.parse ...

  3. python post上传大文件分片上传_基于七牛 用python实现分片上传 创建文件报错701...

    创建文件时出错: 701 Unknown {"error":"block 0: yonginvalid context"} 抓包结果: POST /mkfile ...

  4. python实现文件下载-python实现上传下载文件功能

    最近刚学python,遇到上传下载文件功能需求,记录下! django web项目,前端上传控件用的是uploadify. 文件上传 - 后台view 的 Python代码如下: @csrf_exem ...

  5. python 文件上传下载,python实现上传下载文件功能

    最近刚学python,遇到上传下载文件功能需求,记录下! django web项目,前端上传控件用的是uploadify. 文件上传 - 后台view 的 Python代码如下: @csrf_exem ...

  6. 移动端上传大文件到服务器,android上传大文件到服务器地址

    android上传大文件到服务器地址 内容精选 换一换 安装传输工具在本地主机和Windows云服务器上分别安装数据传输工具,将文件上传到云服务器.例如QQ.exe.在本地主机和Windows云服务器 ...

  7. 并发编程知识总结,软件开发架构,socket套接字模板,粘包问题,struct解决粘包问题,上传大文件数据,socketserver,关于操作系统的发展史,进程,线程。...

    并发编程知识总结 软件开发架构 C/S: client:客户端 server:服务端 优点:占用网络资源少,软件的使用稳定 缺点:服务端更新后,客户端也要更新,需要使用多个软件,需要下载多个客户端 B ...

  8. Git入门之命令行删除文件及上传大文件至Github(二)

    自2013年开始,作者的代码基本是分享到CSDN下载区,最早设置均是免费的,但随着下载量增加,分数自动增长.为了更好地分享开源代码及相关工具,赶上时代潮流,作者后续会将代码分享至Github和CSDN ...

  9. 用ASP.NET上传大文件

    作者:思归     微软MVP   http://blog.joycode.com/saucer/ 我们在上传大文件时都遇到过这样或那样的问题.设置很大的maxRequestLength值并不能完全解 ...

最新文章

  1. 怎样使用fastJson发送数组格式的Json数据
  2. python 异常函数调用栈_Python捕获异常堆栈信息的几种方法
  3. hdu 3062 Party(2-sat,3级)
  4. gcn语义分割_语义分割该如何走下去?
  5. c语言计算火车的运行时间_C++火车入轨算法的实现代码
  6. [译] iOS 设计模式进阶
  7. python使用os库临时改变环境变量
  8. 统计系统中所有进程占用内存的方法
  9. 数值计算原理_数值方法中的有限元法、有限差分法、有限体积法的区别
  10. 元数据是什么?举例告诉你什么是元数据
  11. Android数据库框架Sugar的使用
  12. 当RPM包安装遇上“依赖性”问题时的解决办法
  13. 小武学fpgaStep2
  14. java科技说明文范文800_说明文范文:生活因成功而精彩
  15. 联想ThinkServer RS260服务器静音降噪改造及CentOS拷机测试
  16. 2019阿里暑期实习一面
  17. 编程之路第11天:解决此前截屏权限需要手动点击确认问题(打开双线程)
  18. STM32——USART串口
  19. 模拟退火算法全解(Simulated Annealing)文末有源码
  20. STM32单片机蓝牙APP手势语音温控电风扇落地扇人体感应

热门文章

  1. 红蓝攻防对抗中需要掌握的网络安全技术汇总
  2. 【数字信号去噪】基于matlab改进的小波模极大值数字信号去躁【含Matlab源码 1710期】
  3. 欧盟数字市场负责人:大科技公司垄断令人担忧
  4. ## 耳机插入电脑无声音,疑难解答显示“音频服务无响应”的一种解决思路:
  5. 【机器学习】XGBoost
  6. 持久内存BTT实现及优化(二)
  7. 大数据知识(六):Hadoop练习
  8. 参数估计、点估计、极大似然估计
  9. 朴素贝叶斯(Naive Bayes)(原理+Python实现)
  10. Excel批量删除换行符_clean函数