`
no_bao
  • 浏览: 315814 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

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

    博客分类:
  • j2ee
 
阅读更多

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

理论

简单的HTTP POST

大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下:

<form method="post"action="http://w.sohu.com" >

         <inputtype="text" name="txt1">

         <inputtype="text" name="txt2">

 </form>

提交时会向服务器端发出这样的数据(已经去除部分不相关的头信息),数据如下:

 

POST / HTTP/1.1

Content-Type:application/x-www-form-urlencoded

Accept-Encoding: gzip, deflate

Host: w.sohu.com

Content-Length: 21

Connection: Keep-Alive

Cache-Control: no-cache

 

txt1=hello&txt2=world

 

对于普通的HTML Form POST请求,它会在头信息里使用Content-Length注明内容长度。头信息每行一条,空行之后便是Body,即“内容”(entity)。它的Content-Type是application/x-www-form-urlencoded,这意味着消息内容会经过URL编码,就像在GET请 求时URL里的QueryString那样。txt1=hello&txt2=world

POST上传文件

最早的HTTP POST是不支持文件上传的,给编程开发带来很多问题。但是在1995年,ietf出台了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以Content-Type的类型扩充了multipart/form-data用以支持向服务器发送二进制数据。因此发送post请求时候,表单<form>属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:

 ①application/x-www-form-urlencoded(默认值)
 ②multipart/form-data
其实form表单在你不写enctype属性时,也默认为其添加了enctype属性值,默认值是enctype="application/x- www-form-urlencoded".

 

通过form表单提交文件操作如下:

<form method="post"action="http://w.sohu.com/t2/upload.do" enctype=”multipart/form-data”>

         <inputtype="text" name="desc">

         <inputtype="file" name="pic">

 </form>

 

浏览器将会发送以下数据:

POST /t2/upload.do HTTP/1.1

User-Agent: SOHUWapRebot

Accept-Language: zh-cn,zh;q=0.5

Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7

Connection: keep-alive

Content-Length: 60408

Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Host: w.sohu.com

 

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Content-Disposition: form-data;name="desc"

Content-Type: text/plain; charset=UTF-8

Content-Transfer-Encoding: 8bit

 

[......][......][......][......]...........................

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC

Content-Disposition: form-data;name="pic"; filename="photo.jpg"

Content-Type: application/octet-stream

Content-Transfer-Encoding: binary

 

[图片二进制数据]

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--

 

我们来分析下数据,第一个空行之前自然还是HTTP header,之后则是Entity,而此时的Entity也比之前要复杂一些。根据RFC 1867定义,我们需要选择一段数据作为“分割边界”( boundary属性),这个“边界数据”不能在内容其他地方出现,一般来说使用一段从概率上说“几乎不可能”的数据即可。 不同浏览器的实现不同,例如火狐某次post的  boundary=---------------------------32404670520626 , opera为boundary=----------E4SgDZXhJMgNE8jpwNdOAX ,每次post浏览器都会生成一个随机的30-40位长度的随机字符串,浏览器一般不会遍历这次post的所有数据找到一个不可能出现在数据中的字符串,这样代价太大了。一般都是随机生成,如果你遇见boundary值和post的内容一样,那样的话这次上传肯定失败,不过我建议你去买彩票,你太幸运了。Rfc1867这样说明{A boundary is selected that does not occur in any of the data. (This selection is sometimes done probabilisticly.)}。

 

 

选择了这个边界之后,浏览器便把它放在Content-Type 里面传递给服务器,服务器根据此边界解析数据。下面的数据便根据boundary划分段,每一段便是一项数据。(每个field被分成小部分,而且包含一个value是"form-data"的"Content-Disposition"的头部;一个"name"属性对应field的ID,等等,文件的话包括一个filename)

  • IE和Chrome在filename的选择策略上有所不同,前者是文件的完整路径,而后者则仅仅是文件名。
  • 数据内容以两条横线结尾,并同样以一个换行结束。在网络协议中一般都以连续的CR、LF(即\r、\n,或0x0D、Ox0A)字符作为换行,这与Windows的标准一致。如果您使用其他操作系统,则需要考虑它们的换行符

 另外Content-length 指的是所用数据的长度。

实现

httpClient4如何实现

httpClient4使用http-mime.jar包的MultipartEntity实现,代码如下(为了简洁,处理了异常处理代码):

                           

HttpPost httpPost = newHttpPost(url);

Log.debug("post url:"+url);

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");

 

MultipartEntity mutiEntity = newMultipartEntity();

File file = new File("d:/photo.jpg");

mutiEntity.addPart("desc",new StringBody("美丽的西双版纳", Charset.forName("utf-8")));

mutiEntity.addPart("pic", newFileBody(file));

 

 

httpPost.setEntity(mutiEntity);

HttpResponse  httpResponse = httpClient.execute(httpPost);

HttpEntity httpEntity =  httpResponse.getEntity();

String content = EntityUtils.toString(httpEntity);

                           

分享到:
评论

相关推荐

    解决java enctype multipart form-data文件上传传值问题

    ### 解决Java enctype "multipart/form-data" 文件上传传值问题 在Java Web开发中,处理文件上传是一项常见的任务。特别是当涉及到使用`multipart/form-data`作为表单的编码类型时,这种需求更为突出。本文将深入...

    基于form-data请求格式详解

    值得一提的是,在HTML中,表单上传文件时必须设置其enctype属性为multipart/form-data,因为默认值是application/x-www-form-urlencoded,这不支持文件上传。 JavaScript中,XMLHttpRequest Level 2引入了FormData...

    http以post方式上传一个文件[文].pdf

    在实际应用中,我们可以使用 multipart/form-data 格式来上传文件和表单数据,以便在服务器端进行处理和存储。同时,我们也可以使用其他格式,如 application/x-www-form-urlencoded,来上传文件和表单数据。 ...

    htpp上传文件包

    在给定的例子中,这是一个`POST`类型的请求,目标是`upload.jsp`文件,并且使用了`multipart/form-data`作为内容类型,这通常用于文件上传场景。 ### multipart/form-data MIME类型 在HTTP协议中,当需要上传文件...

    前端大厂最新面试题-file_upload.docx

    multipart/form-data 是一种特殊的 Content-Type,用于上传文件。在 HTTP 协议中,multipart/form-data 是一种混杂的资源类型,由多个元素组成。它可以用于上传文件,例如图片、视频等。 四、Content-Disposition ...

    前端开源库-fastify-multipart

    `fastify-multipart` 就是这样一个插件,专门用于处理 `multipart/form-data` 类型的数据,即通常用于文件上传的格式。 1. **Fastify 框架介绍** Fastify 以其高性能和低开销著称,它的设计目标是提供快速、灵活且...

    文件上传机制代码详解

    &lt;form action="servlet" method="post" enctype="multipart/form-data"&gt; &lt;input type="file" name="uploadFile" /&gt; 上传" /&gt; &lt;/form&gt; ``` `servlet`可能是处理文件上传的Servlet类,其关键在于解析多部分请求。在...

    http1867协议中文版

    以下是一个具体的示例,展示了如何使用`multipart/form-data`和`&lt;input type="file"&gt;`创建一个文件上传表单: ```html &lt;form enctype="multipart/form-data" action="/upload" method="post"&gt; 选择文件: 上传"&gt; ...

    asp无组件上传功能

    ASP需要解析接收到的POST请求中的`multipart/form-data`数据。这通常涉及到读取请求体,识别边界,然后提取文件名、文件类型和文件内容。 3. **临时文件存储** ASP将接收到的文件内容写入服务器上的临时文件,以...

    Springmvc上传文件.docx

    首先,我们需要创建一个可以上传文件的表单,表单的 enctype 属性必须设置为 "multipart/form-data",否则无法上传文件。例如: ```html &lt;form action="mapping_address" method="post" enctype="multipart/form-...

    jsp文件上传功能的实现

    文件上传时,客户端发送的数据格式是“multipart/form-data”,这表示表单数据由多个部分组成,包括文件数据。 2. **表单元素**: - 要上传文件,需要在HTML表单中使用`&lt;input type="file"&gt;`标签。同时,表单的`...

    fileupload使用详解

    &lt;form action="upload" method="post" enctype="multipart/form-data"&gt; &lt;input type="file" name="file" /&gt; 上传" /&gt; &lt;/form&gt; ``` 5. **处理上传请求** 在Servlet或Filter中解析请求并处理文件上传。首先,...

    Struts2 上传文件

    &lt;form id="form1" name="form1" enctype="multipart/form-data" method="post" action="uploadAction"&gt; 上传文件:&lt;input type="file" name="uploadFile"/&gt;&lt;br/&gt; 请求参数:&lt;input type="text" name="wawa"/&gt;&lt;br/&gt;...

    09_尚硅谷_文件的上传和下载_王振国 - 课堂笔记1

    文件上传和下载技术详解 文件上传和下载是许多系统和软件中常见的功能,例如QQ头像、邮箱附件、OA系统审批等。文件上传和下载技术是指用户将文件从客户端上传到服务器端,或者从服务器端下载到客户端的过程。 文件...

    jsp file up

    5. **Commons FileUpload库**:Apache Commons FileUpload是一个常用的Java库,用于解析`multipart/form-data`编码的数据,包括文件上传。它可以处理多个文件上传,以及设置上传限制等。 6. **DiskFileItemFactory...

    struts2上传

    &lt;form action="upload.action" method="post" enctype="multipart/form-data"&gt; 标题:&lt;input type="text" name="title"/&gt; 选择文件:&lt;input type="file" name="upload"/&gt; 上传" type="submit"/&gt; &lt;/form&gt; ...

Global site tag (gtag.js) - Google Analytics