HTTP协议之multipart/form-data请求分析

首先来了解什么是multipart/form-data请求:

根据http/1.1 rfc 2616的协议规定,我们的请求方式只有OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE等,那为为何我们还会有multipart/form-data请求之说呢?这就要从头来说了。

http协议大家都知道是规定了以ASCII码传输,建立在tcp、ip协议之上的应用层规范,规范内容把http请求分为3个部分:状态行,请求头,请求体。所有的方法、实现都是围绕如何运用和组织这三部分来完成的。换句话来说就是万变不离其中,只要我们了解了http请求的组成部分后,自然就可以应变任何实际工作中的需求和问题了。

关于状态行,请求头,请求体等三部分的具体内容,大家可以参考官方的协议文档http://www.faqs.org/rfcs/rfc2616.html,这里主要分析multipart/form-data请求具体是怎么一回事。

既然http协议本身的原始方法不支持multipart/form-data请求,那这个请求自然就是由这些原始的方法演变而来的,具体如何演变且看下文:

multipart/form-data的基础是post请求,即基于post请求来实现的
multipart/form-data形式的post与普通post请求的不同之处体现在请求头,请求体2个部分
multipart/form-data请求头:
必须包含Content-Type信息,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中不同参数的内容(普通post请求的参数分割符默认为&,参数与参数值的分隔符为=)。具体的头信息格式如下:

Content-Type: multipart/form-data; boundary= b o u n d 其 中 {bound} 其中 bound{bound} 是一个占位符,代表我们规定的具体分割符;可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容。如:--------------------56423498738365

样例:

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

multipart/form-data请求体:
它也是一个字符串,不过和普通post请求体不同的是它的构造方式。普通post请求体是简单的键值对连接,格式如下:

k1=v1&k2=v2&k3=v3
而multipart/form-data则是添加了分隔符、参数描述信息等内容的构造体。具体格式如下:

${bound}
Content-Disposition: form-data; name=“Filename”

HTTP.pdf
${bound}
Content-Disposition: form-data; name=“file000”; filename=“HTTP协议详解.pdf”
Content-Type: application/octet-stream

%PDF-1.5
file content
%%EOF
${bound}
Content-Disposition: form-data; name=“Upload”

Submit Query
b o u n d − − 其 中 {bound}-- 其中 bound{bound}就是之前请求头信息中的分割符,如果头信息中规定为123,那么这里也要为123(其作用等同于普通post请求中的&符号的作用,即分割参数)。很明显如果按照之前请求头的样例来,则这里的 b o u n d 值 应 该 替 换 为 − − − − − − − − − − − − − − − − − − − − 56423498738365 , 注 意 最 后 一 个 {bound}值应该替换为--------------------56423498738365,注意最后一个 bound56423498738365{bound}后需要固定添加两个横杆–

另外可以很容易的看出,这个请求体被分隔符划分为3个部分,而每个部分其实就是一个参数的键值描述(其作用等同于普通post请求的k1=v1的部分),但对参数信息的描述可以比普通post请求更加丰富,这就是为什么multipart/form-data能发送文件的原因。

每一个部分都是以分隔符开始的,接着是该部分内容的描述信息,然后是一个回车,最后是描述信息的具体内容。如果传送的内容是一个文件的话,那么还会包含文件名信息,以及文件内容的类型;上面的第二个小部分其实是一个文件体的结构,最后的分割符后会以–结尾,表示请求体结束。

综上,可以知道要发送一个multipart/form-data的请求,其实任何支持post请求的工具或语言都可以支持,只是自己要稍微包装一下便可。

参考资料:
百度百科: http://baike.baidu.com/view/9472.htm

http1.1协议规范: http://www.faqs.org/rfcs/rfc2616.html

分析工具:httpAnalyzer

==纯文本格式分割线=

Header = {“Content-type” : “multipart/form-data, boundary=AaB03x”}

Data = “–AaB03x\r\n” +
“content-disposition: form-data; name=“field1”\r\n” +
“\r\n” +
“Joe Blow\r\n” +
“–AaB03x\r\n” +
“content-disposition: form-data; name=“pics”; filename=“file1.txt”\r\n” +
“Content-Type: text/plain\r\n” +
“\r\n” +
“…binary contents of file1.txt …\r\n” +
“–AaB03x–\r\n”
其中:…binary contents of file1.txt … 要替换成真实的文件二进制内容。

=请求代码分割线==

你可能感兴趣的:(基本原理,http)