<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>下载 on 勇气</title><link>https://courages.us/tag/%E4%B8%8B%E8%BD%BD/</link><description>Recent content in 下载 on 勇气</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 03 Oct 2016 12:30:09 +0800</lastBuildDate><atom:link href="https://courages.us/tag/%E4%B8%8B%E8%BD%BD/index.xml" rel="self" type="application/rss+xml"/><item><title>HTTP文件分块上传下载</title><link>https://courages.us/http%E6%96%87%E4%BB%B6%E5%88%86%E5%9D%97%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD/</link><pubDate>Sun, 02 Oct 2016 22:16:47 +0800</pubDate><guid>https://courages.us/http%E6%96%87%E4%BB%B6%E5%88%86%E5%9D%97%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD/</guid><description>&lt;p&gt;在开发中经常需要上传下载文件，涉及web页面，手机应用，线下服务器等，文件传输方式有HTTP，FTP，BT。。于是基于HTTP开发了统一文件上传下载接口。&lt;br&gt;&#10;由于上传涉及多端，网络状况复杂，需要能够支持断点续传，因此需要对文件进行分块和校验。&lt;br&gt;&#10;请求上传：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;chunk：当前块编号&lt;/li&gt;&#10;&lt;li&gt;chunks：文件分块总数&lt;/li&gt;&#10;&lt;li&gt;md5：整个文件md5&lt;/li&gt;&#10;&lt;li&gt;content：文件块内容&lt;/li&gt;&#10;&lt;li&gt;size：文件块大小&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;服务端返回:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;statu：状态，0失败，非0成功&lt;/li&gt;&#10;&lt;li&gt;chunk：需要上传的块编号&lt;/li&gt;&#10;&lt;li&gt;message：操作信息&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;服务端有几种情况&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;1. 上传成功，md5已经存在，说明文件已存在，则返回上传成功，并结束上传，类似秒传&lt;/li&gt;&#10;&lt;li&gt;2. 上传成功，md5已经不存在，但当前文件块已经存在，说明该文件已经上传过一部分，则返回成功，并给出需要开始上传的块号，类似断点续传&lt;/li&gt;&#10;&lt;li&gt;3. 上传成功，文件块不存在，当前块号小于总块数减一，则返回上传成功，并给出下一块块号&lt;/li&gt;&#10;&lt;li&gt;4. 上传成功，文件块不存在，当前块号等于总块数减一，进行合并，校验成功，则返回上传成功，并结束上传&lt;/li&gt;&#10;&lt;li&gt;5. 上传成功，文件块不存在，当前块号等于总块数减一，进行合并，校验成功，则返回上传失败，从第一块重新开始上传&lt;/li&gt;&#10;&lt;li&gt;6. 上传失败，服务端返回失败，则根据错误信息重传&lt;/li&gt;&#10;&lt;li&gt;7. 上传失败，服务端没有返回，则重传当前块&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;客户端依据自定义的大小对文件进行切割，每次传递一个块，当服务端接收到当前块号为总块数减一则认为全部上传完毕，进行文件块合并，清除临时文件块，计算MD5，如果MD5与传递过来的相等则认为上传成功，否则失败，要求客户端从第一块重传。&lt;br&gt;&#10;这个是基于客户端顺序上传的，假如是并发上传呢？那么就需要在每个分块上传结束后触发合并，需要借助锁来管理。&lt;br&gt;&#10;&lt;a class="link" href="https://github.com/upyun/js-multipart-upload/wiki/%E5%88%86%E5%9D%97%E4%B8%8A%E4%BC%A0%E8%AF%B4%E6%98%8E" target="_blank" rel="noopener"&#10; &gt;又拍云表单分块上传&lt;/a&gt;则分为3步骤：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;1.初始化，上报文件信息&lt;/li&gt;&#10;&lt;li&gt;2.上传分块&lt;/li&gt;&#10;&lt;li&gt;3.上传结束，触发合并&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;而&lt;a class="link" href="http://fex.baidu.com/webuploader/" target="_blank" rel="noopener"&#10; &gt;百度的WebUploader&lt;/a&gt;则支持浏览器向服务端的断点续传，利用HTML5或Flash对文件进行分块，计算MD5。&lt;br&gt;&#10;HTTP分块下载，也就是断点续传下载，是根据HTTP1.1协议（RFC2616）中定义的HTTP头 Range和Content-Range字段来控制的：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;1. 客户端在HTTP请求头里面指明Range，即开始下载位置&lt;/li&gt;&#10;&lt;li&gt;2. 服务端在HTTP响应头里面返回Content-Range，告知下载其实点和范围&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;服务端可以将文件MD5等加入Etag或自定义Header字段里面，HTTP客户端便可以分开请求数据，最后合并；否则永远都是从头开始。其实也可以把大文件切成多个小文件，再一个个下载回来合并。&lt;br&gt;&#10;有些web服务器直接支持文件上传和下载的断点续传，比如Nginx。&lt;/p&gt;&#10;&lt;p&gt;刚才的文件分块传输过程，有点像TCP通信，也有建立连接，分片，校验，重发，断开连接。&lt;br&gt;&#10;而这个将大任务分解为多个小任务进行处理的思想，即准备–&amp;gt;循环（并行）处理–&amp;gt;结束，可以应用到很多项目里面，比如大数据，爬虫。为Web管理系统写了jQuery插件用来处理的耗时任务，将一个耗时任务分解为多个循环请求，避免超时&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;1. prepare：服务端返任务标示ID，总步骤，及附加参数&lt;/li&gt;&#10;&lt;li&gt;2. process：根据返回参数进行循环请求&lt;/li&gt;&#10;&lt;li&gt;3. complete:循环完成，触发结束&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;后面又延伸出另外一个插件，支持任意顺序步骤的处理。&lt;/p&gt;&#10;&lt;p&gt;参考链接：&lt;br&gt;&#10;&lt;a class="link" href="https://github.com/kazaff/me.kazaff.article/blob/master/%E8%81%8A%E8%81%8A%E5%A4%A7%E6%96%87%E4%BB%B6%E4%B8%8A%E4%BC%A0.md" target="_blank" rel="noopener"&#10; &gt;聊聊大文件上传&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="https://github.com/blueimp/JavaScript-MD5" target="_blank" rel="noopener"&#10; &gt;md5 javascript&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://blog.csdn.net/xifeijian/article/details/8712439" target="_blank" rel="noopener"&#10; &gt;HTTP协议－－断点续传&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://blog.chinaunix.net/uid-25267728-id-4095080.html" target="_blank" rel="noopener"&#10; &gt;http断点续传的秘密&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.linuxprobe.com/nginx-upload-module.html" target="_blank" rel="noopener"&#10; &gt;nginx-upload-module模块实现文件断点续传&lt;/a&gt;&lt;br&gt;&#10;&lt;a class="link" href="http://www.cnblogs.com/jony413/articles/4906854.html" target="_blank" rel="noopener"&#10; &gt;通过curl测试服务器是否支持断点续传&lt;/a&gt;&lt;/p&gt;&#10;</description></item></channel></rss>