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

你可能感兴趣的文章
pytest+allure使用动态级别,参数化severity
查看>>
Pytest+Unittest+Git+Jenkins企业级CICD自动化测试平台建设方案
查看>>
Pytest+Yaml 数据驱动测试用例
查看>>
pytest-base-url插件之配置可选的项目系统URL
查看>>
pytest-xdist 进行多进程并发测试!
查看>>
pytest-xdist:远程多主机 - 分布式运行自动化测试
查看>>
Pytest中进行测试环境切换:pytest_addoption!
查看>>
pytest利用request fixture实现个性化测试需求详解
查看>>
pytest单元测试实战
查看>>
pytest单元测试框架
查看>>
Pytest参数详解 — 基于命令行模式
查看>>
pytorch cv2 plt transforms pause waitforbuttonpress一个完整的图片处理程序
查看>>
pytest学习和使用 - Pytest用例执行结果有哪几种状态?
查看>>
pytest实战技巧之参数化应用!
查看>>
Pytest实践:Python测试技术基础知识!
查看>>
Pytest数据驱动怎么玩?实战教程来了!
查看>>
Pytest框架 之【用例执行顺序】
查看>>
Pytest框架中的测试用例执行方式!
查看>>
pytest框架快速入门-pytest运行时参数说明,pytest详解,pytest.ini详解
查看>>
Pytest框架环境切换实战教程!赶快收藏
查看>>