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表单提交文件操作如下:                                                      设置编码方式(enctype)为multipart/form-data

<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 指的是所用数据的长度。

参考:

Rfc1867:http://www.ietf.org/rfc/rfc1867

Rfc1867:http://www.vivtek.com/rfc1867.html

时间: 2024-10-13 07:12:05

Multipart/form-data POST文件上传的相关文章

Ajax(form表单文件上传、请求头之contentType、Ajax传递json数据)

form表单文件上传 上菜 file_put.html <form action="" method="post" enctype="multipart/form-data"> {# 这里必须要请求头格式才能把上传文件的对象传过去 enctype="multipart/form-data"#} 姓名 <input type="text" name="user">

WebApi实现Ajax模拟Multipart/form-data方式多文件上传

前端页面代码: <input type="file" class="file_control" /><br /> <input type="file" class="file_control" /><br /> <input type="file" class="file_control" /> <button id=&q

multipart/form-data请求与文件上传

要上传文件,需要用post方法,并且设置enctype为multipart/form-data. <form action="/upload" method="post" enctype="multipart/form-data"> <input type="text" name="param1"> <input type="text" name="

form表单文件上传

创建一个form表单 #上传文件的时候,enctype属性改成multipart/form-data <from action='' method='post' enctype='multipart/form-data'> <input type='file' name='avatar'> <input type='submit'> </from> 服务器接收 #服务器接收的时候,文件被放在request.FILES中 def file_put(reques

Spring 4 官方文档学习(十一)Web MVC 框架之multipart(文件上传)支持

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-multipart 1.简介 Spring内置的multipart支持会处理web应用中的文件上传.你可以启用该支持 -- 通过可插拔的MultipartResolver对象们,它们都是定义在 org.springframework.web.multipart 包中.Spring提供了一个MultipartResolver实

使用multipart请求处理文件上传

在开发Web应用程序时比较常见的功能之一,就是允许用户利用multipart请求将本地文件上传到服务器,而这正是Grails的坚固基石--Spring MVC其中的一个优势.Spring通过对Servlet API的HttpServletRequest接口进行扩展,使其能够很好地处理文件上传.扩展后的接口名为org.springframework.web.multipart.MultipartHttpServletRequest,其内容如清单7-31所示. 清单7-31 org.springfr

JavaWeb之文件上传与下载&amp;邮件技术(十八)

文件上传 简介 最近发现这几篇很少写简介,说自己没时间写,可能是说服自己吧.总之能多写就多写.还有个一直存在的问题,每天写的博客质量不是很好.再次说服自己,现在处于学习阶段,写博客为了巩固知识点,以便后期作复习使用.其实我每次写博客之前笔记老早都在nopad++上写好了,所以大部分在wlw上直接粘贴的,请见谅 1. 文件上传必要前提 1. form表单:属性enctype必须取值为multipart/form-data enctype的默认值是:application/x-www-form-ur

python Django之文件上传

python Django之文件上传 使用Django框架进行文件上传共分为俩种方式 一.方式一 通过form表单进行文件上传 #=========================================FORM表单上传文件======================================== def f1(request): #定义f1上传函数 if request.method=='GET': #如果是以GET请求 return render(request,'f1.htm

WebApi发送HTML表单数据:文件上传与多部分MIME

5.3 Sending HTML Form Data5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/2826230.html By Mike Wasson|June 21, 2012作者:Mike Wasson | 日期:2012-6-21 Part 2: File Upload and Multipart MIME第2部分:文件上传与多部分MIME This tutorial shows how to

(转)WebApi发送HTML表单数据:文件上传与多部分MIME

5.3 Sending HTML Form Data5.3 发送HTML表单数据(2) 本文引自:http://www.cnblogs.com/r01cn/archive/2012/12/20/2826230.html By Mike Wasson|June 21, 2012作者:Mike Wasson | 日期:2012-6-21 Part 2: File Upload and Multipart MIME第2部分:文件上传与多部分MIME This tutorial shows how to