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

你可能感兴趣的文章
Palo Alto Networks PAN-OS身份认证绕过导致RCE漏洞复现(CVE-2024-0012)
查看>>
Panalog 日志审计系统 libres_syn_delete.php 前台RCE漏洞复现
查看>>
Panalog 日志审计系统 sprog_deletevent.php SQL 注入漏洞复现
查看>>
pandas :将时间戳转换为 datetime.date
查看>>
pandas DataFrame 中的自定义浮点格式
查看>>
Pandas 对数据框的布尔比较
查看>>
Pandas 读取具有浮点值的 csv 文件会导致奇怪的舍入和小数位数
查看>>
pandas 适用,但仅适用于满足条件的行
查看>>
Pandas-通过对列和索引的值求和来合并两个数据框
查看>>
pandas.read_csv()的详解-ChatGPT4o作答
查看>>
Pandas数据可视化怎么做?用实战案例告诉你!
查看>>
Pandas数据结构之DataFrame常见操作
查看>>
pandas整合多份csv文件
查看>>
pandas某一列转数组list
查看>>
Pandas模块,我觉得掌握这些就够用了!
查看>>
Pandas玩转文本处理!
查看>>
pandas的to_sql方法中使用if_exists=‘replace‘
查看>>
pandas读取parquet报错
查看>>
Pandas进阶大神!从0到100你只差这篇文章!
查看>>
spring5-介绍Spring框架
查看>>