`
bluky999
  • 浏览: 715425 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

HTTP协议上的文件上传

阅读更多

1 HTTP协议上的文件上传,最频繁的应用场景了。 RFC1867里定义的标准HTTP协议POST报文格式如下:

 

 

HEADER:

 

 写道
......
Content-Type: multipart/form-data;
 

 

BODY:

 

Content-type: multipart/form-data, boundary=AaB03x

        --AaB03x
        content-disposition: form-data; name="field1"

        Joe Blow
        --AaB03x
        content-disposition: form-data; name="pics"
        Content-type: multipart/mixed, boundary=BbC04y

        --BbC04y
        Content-disposition: attachment; filename="file1.txt"

 

 

注释:

1 传文件的时候 使用的Media Type name: multipart , Media subtype name: form-data

2 boundary用来标识分割不同的field,其中文件是一个特殊的field

3 多个文件的时候得继续制定 Content-type: multipart/mixed ,同时定义新的 boundary

4 不同的field注意区分 Content-disposition 的值,是 form/data 还是 attachment

5 这里定义的是POST方式的上传,不针对PUT 。

 

 

2 如果需求非常确定每次请求只上传一个文件,那么我们可以不使用HTTP约定的这种方式,而改用一种更简单直接的方式:

 

- 在 HEDER 里的 POST 后的URL里携带普通参数 field

- 在 BODY里直接装在要上传的文件内容,抛弃任何格式等约束

- 服务端直接从BODY里读取流数据保存为文件,其他参数从URL里读取

 

这样以来HTTP报文就类似:

 

HEDER

 

 写道
POST /HttpFileServer/upload?filename=nodexy.zip&fid=t01 HTTP/1.1
Host: www.yangzt.com:9190
Content-Length: xxxxx
 

BODY

 

 写道
文件内容

 

注释:

1 这不是标准的文件上传方式,但仍然是标准的HTTP报文

2 这种私有约定的方式,需要服务端和客户端同时特异化处理

3 针对每次请求只传一个文件的需求,这样改良后就会比较简洁,至于效率上是否有明显差别还不得而知,未做测试对比

 

 

3 总结:

 

在HTTP协议这一层上做文件的上传下载,也是很常见的方式,尤其很多移动应用里会采用;因为对客户端来说打开一个URL来GET或POST数据,相比打开一个scocke连接来读取或写入数据要简单得多,实现也快捷高效。

 

HTTP协议上的上传下载,也可以轻松实现断点续传,和进度反馈等,主要依赖length和range两个值。所以作为标准考虑,一定要明确地设置header里的length属性 --- 如果不设置,对于一般浏览器来说无碍,仍然可以成功下载,但是对于诸如libcurl这样的类库来说则无法取到数据。

 

另外,TCP协议层上的文件上传下载,也是很常见的应用场景,改日再次涉及另作详谈。

 

0
0
分享到:
评论
1 楼 bluky999 2011-11-21  
以上2中提到的改良策略,是无法直接在客户端使用 HttpClient 或在服务端使用common-upload等现有模块来实现的,因为封装越多则灵活性也越低。 所以建议直接面向 HTTP协议编程,客户端使用 HttpUrlConnection 。

相关推荐

Global site tag (gtag.js) - Google Analytics