博客
关于我
Multipart/form-data POST文件上传详解
阅读量:206 次
发布时间:2019-02-28

本文共 2573 字,大约阅读时间需要 8 分钟。

Multipart/form-data POST文件上传详解

理论

简单的HTTP POST

通过HTTP向服务器发送POST请求提交数据,通常是通过form表单提交的。以下是一个简单的form表单代码示例:

提交时,服务器会接收如下的数据(已去除部分不相关的头信息):

POST / HTTP/1.1Content-Type: application/x-www-form-urlencodedAccept-Encoding: gzip, deflateHost: w.sohu.comContent-Length: 21Connection: Keep-AliveCache-Control: no-cachetxt1=hello&txt2=world

普通的HTML Form POST请求会在头信息中使用Content-Length注明内容长度,Body部分则包含URL编码后的数据。

POST上传文件

HTTP最初不支持文件上传,但1995年rfc1867(《Multiparty/form-data在HTTP中》)的发布使得文件上传成为可能。为了支持文件上传,form表单的enctype属性可以设置为multipart/form-data:

浏览器会发送以下数据(注:部分示例简化):

POST /t2/upload.do HTTP/1.1User-Agent: SOHUWapRebotAccept-Language: zh-cn,zh;q=0.5Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7Connection: keep-aliveContent-Length: 60408Content-Type: multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXCHost: w.sohu.com--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXCContent-Disposition: form-data; name="desc"Content-Type: text/plain; charset=UTF-8Content-Transfer-Encoding: 8bit--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXCContent-Disposition: form-data; name="pic"; filename="photo.jpg"Content-Type: application/octet-streamContent-Transfer-Encoding: binary--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--

文件上传的关键在于boundary边界的选择和数据的分段。服务器根据boundary分割数据,解析每个部分的内容。

数据格式分析

数据以以下格式组织:

  • 头信息(HTTP header):包含Content-Length、Content-Type、Host等。
  • 实体部分(Entity):包含边界分隔的数据块。

每个数据块包含以下信息:

  • --boundary
  • Content-Disposition: form-data; name="字段名"
  • Content-Type: 内容类型(如text/plain或application/octet-stream)
  • Content-Transfer-Encoding: 8bit或binary
  • 数据内容

注意事项:

  • 不同浏览器生成的boundary不同,但浏览器不会在数据中随机出现这个boundary。
  • IE和Chrome对filename的处理不同,前者返回完整路径,后者仅返回文件名。

实现

HttpClient4的实现示例

HttpClient4通过MultipartEntity实现文件上传。以下是代码示例:

HttpPost httpPost = new HttpPost(url);httpPost.setDefaultCloseOperation(HttpPost.ERROR_OK);// 设置请求头httpPost.setHeader("User-Agent", "SOHUWapRebot");httpPost.setHeader("Accept-Language", "zh-cn,zh;q=0.5");httpPost.setHeader("Accept-Charset", "GBK,utf-8;q=0.7,*;q=0.7");httpPost.setHeader("Connection", "keep-alive");// 创建MultipartEntityMultipartEntity mutiEntity = new MultipartEntity();File file = new File("d:/photo.jpg");// 添加文本部分mutiEntity.addPart("desc", new StringBody("美丽的西双版纳", Charset.forName("utf-8")));// 添加文件部分mutiEntity.addPart("pic", new FileBody(file));// 设置实体httpPost.setEntity(mutiEntity);// 发送请求HttpResponse httpResponse = httpClient.execute(httpPost);HttpEntity httpEntity = httpResponse.getEntity();String content = EntityUtils.toString(httpEntity);

服务器接收到的数据将包含上传的文件和其他表单字段的值。

总结

文件上传通过Multipart/form-data实现,浏览器生成随机boundary,将文件数据分隔开并发送给服务器。服务器根据boundary解析数据,处理各个部分。

转载地址:http://xams.baihongyu.com/

你可能感兴趣的文章
Objective-C实现cartesianProduct笛卡尔乘积算法(附完整源码)
查看>>
Objective-C实现check strong password检查密码强度算法(附完整源码)
查看>>
Objective-C实现chudnovsky algorithm楚德诺夫斯基算法(附完整源码)
查看>>
Objective-C实现CIC滤波器(附完整源码)
查看>>
Objective-C实现circle sort圆形排序算法(附完整源码)
查看>>
Objective-C实现CircularQueue循环队列算法(附完整源码)
查看>>
Objective-C实现clearBit清除位算法(附完整源码)
查看>>
Objective-C实现climbStairs爬楼梯问题算法(附完整源码)
查看>>
Objective-C实现cocktail shaker sort鸡尾酒排序算法(附完整源码)
查看>>
Objective-C实现cocktailShakerSort鸡尾酒排序算法(附完整源码)
查看>>
Objective-C实现CoinChange硬币兑换问题算法(附完整源码)
查看>>
Objective-C实现collatz sequence考拉兹序列算法(附完整源码)
查看>>
Objective-C实现Collatz 序列算法(附完整源码)
查看>>
Objective-C实现comb sort梳状排序算法(附完整源码)
查看>>
Objective-C实现combinationSum组合和算法(附完整源码)
查看>>
Objective-C实现combinations排列组合算法(附完整源码)
查看>>
Objective-C实现combine With Repetitions结合重复算法(附完整源码)
查看>>
Objective-C实现combine Without Repetitions不重复地结合算法(附完整源码)
查看>>
Objective-C实现conjugate gradient共轭梯度算法(附完整源码)
查看>>
Objective-C实现connected components连通分量算法(附完整源码)
查看>>