假设接受文件的网页程序位于 http://192.168.29.65/upload_file/UploadFile.假设我们要发送一个图片文件,文件名为“kn.jpg”,
首先客户端链接 192.168.24.56 后, 应该发送如下http 请求:
POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.24.56
Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2
User-Agent: WinHttpClient
Content-Length: 3693
Connection: Keep-Alive
-------------------------------7db372eb000e2
Content-Disposition: form-data; name="file"; filename="kn.jpg"
Content-Type: image/jpeg
(此处省略jpeg文件二进制数据...)
-------------------------------7db372eb000e2--
此内容必须一字不差,包括最后的回车,红色字体部分就是协议的头。给服务器上传数据时,并非协议头每个字段都得说明,其中,content-type是必须的,它包括一个类似标志性质的名为boundary的标志,它可以是随便输入的字符串。对后面的具体内容也是必须的。它用来分辨一段内容的开始。Content-Length: 3693 ,这里的3693是要上传文件的总长度。绿色字体部分就是需要上传的数据,可以是文本,也可以是图片等。数据内容前面需要有Content-Disposition, Content-Type以及Content-Transfer-Encoding等说明字段。最后的紫色部分就是协议的结尾了。
注意这一行:
Content-Type: multipart/form-data; boundary=---------------------------7db372eb000e2
根据 rfc1867, multipart/form-data是必须的.
---------------------------7db372eb000e2 是分隔符,分隔多个文件、表单项。其中b372eb000e2 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。Form每个部分用分隔符分割,分隔符之前必须加上"--"着两个字符(即--{boundary})才能被http协议认为是Form的分隔符,表示结束的话用在正确的分隔符后面添加"--"表示结束。
前面的 ---------------------------7d 是 IE 特有的标志,Mozila 为---------------------------71.
每个分隔的数据的都可以用Content-Type来表示下面数据的类型,可以参考rfc1341 (http://www.ietf.org/rfc/rfc1341.txt)
例如 :Contect-Type:image/jpeg 表示下面的数据是jpeg文件数据
============================================================================
[转]通过 http 协议上传文件
在最初的 http 协议中,没有上传文件方面的功能。 rfc1867 ( http://www.ietf.org/rfc/rfc1867.txt ) 为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。
Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。
绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。
各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。
1. 在一个 html 网页中,写一个如下的form :
现在第三方的 http upload file 工具库很多。Jarkata 项目本身就提供了fileupload 包 http://jakarta.apache.org/commons/fileupload/ 。文件上传、表单项处理、效率问题基本上都考虑到了。在 struts 中就使用了这个包,不过是用 struts 的方式另行封装了一次。这里我们直接使用 fileupload 包。至于struts 中的用法,请参阅 struts 相关文档。
这个处理文件上传的 servelet 主要代码如下:
假设我们要发送一个二进制文件、一个文本框表单项、一个密码框表单项。文件名为 E:\s ,其内容如下:(其中的XXX代表二进制数据,如 01 02 03)
注意:Content-Length: 424 这里的424是红色内容的总长度(包括最后的回车)
注意这一行:
Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6
根据 rfc1867, multipart/form-data是必须的.
---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。其中33a816d302b6 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。前面的 ---------------------------7d 是 IE 特有的标志。 Mozila 为---------------------------71
用手工发送这个例子,在上述的 servlet 中检验通过。
注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc1867