测试代码1:
<form action="handle.php" method="post" > <input type="text" name="uname" /><br /> <input type="text" name="email" /><br /> <input type="file" name="file" /><br /> <input type="submit" name="submit" value="提交"/> </form>
浏览器显示效果:
请求头信息:
POST /article/handle.php HTTP/1.1
Host: www.soapstudy.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://www.soapstudy.com/article/postupload.html
Connection: keep-alive
Content-Length : 65
Content-Type: application/x-www-form-urlencoded
消息体:
uname=1234&email=12345&file=desktop.jpg&submit=%E6%8F%90%E4%BA%A4
类似于 get方式传输地址栏中的 参数名1=参数值1&参数名2=参数值2 的形式。
此种方式只是将文件名称通过post方式传输给服务器,仅有名称而无文件信息,这样是无法上传文件的。
测试代码2:
<form action="handle.php" method="post" enctype="multipart/form-data">
<input type="text" name="uname" /><br />
<input type="text" name="email" /><br />
<input type="file" name="file" /><br />
<input type="submit" name="submit" value="提交"/>
</form>
和第一段代码唯一不同的地方是form表单多了属性 enctype=”multipart/form-data” 接着在表单中输入同样的内容提交。
请求头信息
POST /article/handle.php HTTP/1.1
Host: www.soapstudy.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:41.0) Gecko/20100101 Firefox/41.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://www.soapstudy.com/article/postupload.html
Connection: keep-alive
Content-Length:529278
Content-Type:multipart/form-data;boundary=---------------------------11810260022182
和第一种方式不同的地方是 Content-Type, 第一种方式为application/x-www-form-urlencoded;而此种方式为multipart/form-data;boundary=—————————11810260022182。
boundary是用来分割消息体中不同内容的,可以认为是边界,在消息体中可以看到此项应用:
中间那乱七八糟的一大堆的东西应该就是我们的文件信息,这样服务器端收到这些信息以后,就可以将这些信息处理成相应的文件了。
媒体类型multipart/form-data
遵循multipart MIME
数据流定义。
媒体类型multipart/form-data
的数据体由多个部分组成,这些部分由一个固定边界值(Boundary
)分隔。
# 请求头 - 这个是必须的,需要指定Content-Type为multipart/form-data,指定唯一边界值 Content-Type: multipart/form-data; boundary=${Boundary} # 请求体 ${Boundary} Content-Disposition: form-data; name="name of file" Content-Type: application/octet-stream bytes of file ${Boundary} Content-Disposition: form-data; name="name of pdf"; filename="pdf-file.pdf" Content-Type: application/octet-stream bytes of pdf file ${Boundary} Content-Disposition: form-data; name="key" Content-Type: text/plain;charset=UTF-8 text encoded in UTF-8 ${Boundary}
媒体类型multipart/form-data
相对于其他媒体类型如application/x-www-form-urlencoded
等来说,最明显的不同点是:
- 请求头的
Content-Type
属性除了指定为multipart/form-data
,还需要定义boundary
参数 - 请求体中的请求行数据是由多部分组成,
boundary
参数的值模式--${Boundary}
用于分隔每个独立的分部 - 每个部分必须存在请求头
Content-Disposition: form-data; name="${PART_NAME}";
,这里的${PART_NAME}
需要进行URL
编码,另外filename
字段可以使用,用于表示文件的名称,但是其约束性比name
属性低(因为并不确认本地文件是否可用或者是否有异议) - 每个部分可以单独定义
Content-Type
和该部分的数据体 - 求体以
boundary
参数的值模式--${Boundary}--
作为结束标志
- Content-Disposition 指定当前的呈现方式
- Content-Type 传输内容的类型