Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

分块上传、PUT和Content-Range

  对于Range和Content-Range这两个HTTP头,通常我们的理解是Range是请求头,Content-Range是响应头,这个说法是没错,但概念上存在一些问题。确切地说,Range是实体接受者发送的HTTP头,Content-Range是实体发送者发送的HTTP头,而实体的发送者未必是服务器。
  Range是很好用的东西,之前实现多线程下载时就有用到它,每一个GET都负责获取服务器上同一个资源的不同数据块。那么,把GET换成PUT又如何呢?它俩是一对反义词。客户端在下载,服务器就在上传;PUT方法是客户端在上传,服务器则是下载的一方。所以PUT和GET的角色是颠倒的,使用PUT时客户端可以充当服务器发送Content-Range,这样我们就能实现多线程分块上传了。
  但PUT的安全方面问题一直是个梗,分块上传在安全性方面比普通的上传还难处理。不过依然基于MD5做URL的话,使用PUT方法做多线程分块上传还是可以实现的。下面是我的思路:当用户上传数据库后,服务器计算整个数据的MD5来判断整个数据是否都上传完毕。如果没有上传完毕则响应202(Accepted),上传完毕则响应201(Created)。客户端只有收到201响应时才认为自己完全上传成功。对上传不完全的情况还需要另外处理。在首次接受上传时服务器应该创建这个资源,并设置一个计时器,这个计时器期满后如果上传还没完成就释放掉资源,关闭掉正在上传的连接。
  除了安全性问题之外还有一些问题,比如上传过程中资源被GET的情况要怎么处理。虽然以MD5作为URL的话基本不会出现这种情况,因为文件没上传过程中只有上传者知道URL,只要上传者在文件上传完成前不泄露这个URL就可以确保其它用户不访问到一个没上传完成的资源上。或者如果真要解决问题的话,服务器要在接收到数据块时不马上做成相关的资源而作为临时储存,等到MD5验证通过后再创建资源。
  以上的这些想法实现起来都并不困难,连PHP+Apache都可以实现,更何况NodeJS之类的。只是遗憾的是前端对于文件的分块读入需要FileAPI的支持,无法兼容到IE8。
网名:
3.80.55.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^