博客
关于我
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/

你可能感兴趣的文章
Nginx下配置codeigniter框架方法
查看>>
nginx报错:the “ssl“ parameter requires ngx_http_ssl_module in /usr/local/nginx/conf/nginx.conf:128
查看>>
nginx添加模块与https支持
查看>>
Nginx用户认证
查看>>
Nginx的Rewrite正则表达式,匹配非某单词
查看>>
Nginx的使用总结(一)
查看>>
Nginx的使用总结(二)
查看>>
Nginx的可视化神器nginx-gui的下载配置和使用
查看>>
Nginx的是什么?干什么用的?
查看>>
Nginx访问控制_登陆权限的控制(http_auth_basic_module)
查看>>
nginx负载均衡器处理session共享的几种方法(转)
查看>>
nginx负载均衡的5种策略(转载)
查看>>
nginx负载均衡的五种算法
查看>>
Nginx运维与实战(二)-Https配置
查看>>
Nginx配置ssl实现https
查看>>
Nginx配置TCP代理指南
查看>>
Nginx配置——不记录指定文件类型日志
查看>>
Nginx配置代理解决本地html进行ajax请求接口跨域问题
查看>>
Nginx配置参数中文说明
查看>>
Nginx配置好ssl,但$_SERVER[‘HTTPS‘]取不到值
查看>>