如果我们的网站提供文件下载的服务,那么通常我们都希望下载可以断点续传(Resumable Download),也就是说用户可以暂停下载,并在未来的某个时间从暂停处继续下载,而不必重新下载整个文件。

通常情况下,Web服务器(如Apache)会默认开启对断点续传的支持。因此,如果直接通过Web服务器来提供文件的下载,可以不必做特别的配置,即可享受到断点续传的好处。由于这些文件直接通过Web服务器来提供下载,后端脚本无法对这个下载过程进行控制。这对于仅提供公开、静态文件的网站来说不是问题,但对于需要提供私有、动态文件的网站来说,直接通过Web服务器来提供下载就无法满足需求了。这时,就需要在编写后台脚本程序时,加入对断点续传的支持。

本文将以PHP为例,简要介绍实现文件下载断点续传的方法。

原理

断点续传的原理还是比较直观的。

Http协议规定了如何传输某个资源的一部分,而不是全部。比如,有一个文件的大小是1000字节,浏览器可以只请求该文件的前300个字节,或者只请求第500到第1000个字节。通过这种方式,就可以不必在一次请求中传输某个资源的全部内容,而是发起多次请求,每次仅请求其中的一部分内容。等所有这些请求都返回之后,再把得到的内容一块一块的拼接起来得到完整的资源。

实现断点续传就是要利用http协议的上述特性。当用户暂停下载的时候,浏览器会记录已经下载到什么位置,当用户在未来某一时间恢复下载时,就可以从上次暂停的位置继续下载,而不必从头开始。

实现

由于部分传输不是强制的,服务器可以支持也可以不支持,所以,我们需要在程序中告诉浏览器,它请求的资源是否支持部分传输。这可以通过设置HTTP的 Accept-Ranges 响应头信息来实现。PHP代码如下:

代码如下:

header('Accept-Ranges: bytes');

Accept-Ranges: bytes 告诉浏览器,该资源支持以字节为单位的部分传输。这个响应头需要附加在支持部分传输的所有资源上。

当接受到一个请求时,我们需要从浏览器的请求中提取浏览器具体是在请求资源的哪一个部分。这个信息是通过 Range 请求头来传递的。在PHP中,它被存储在$_SERVER['HTTP_RANGE']中。我们需要检查这个变量是否定义了,如果定义了,则使用该值,否则,就将range设为整个资源。

代码如下:

$range = "0-". ($content_length-1);
if(isset($_SERVER['HTTP_RANGE'])){
    $range = $_SERVER['HTTP_RANGE'];
}

接下来,就需要分析 $range 的值,来决定返回资源的哪一部分内容。可能的取值示例:

代码如下:

100-200 // 第100到第200字节
500-    // 第500字节到文件末尾
-1000   // 最后的1000个字节

这里需要注意,得到一个Range之后,你需要对它的取值进行检验,包括:

1.开始位置非负
2.结束位置需要大于开始位置
3.开始位置需要小于文件长度减一 (因为这里的位置索引是从0开始的)
4.若结束位置大于文件长度减一,则需要把它的值设置为文件长度减一

如果Range的取值不合法,则需要终止程序并告知浏览器:

代码如下:

header('HTTP/1.1 416 Requested Range Not Satisfiable');

为了保持文章简洁,具体的校验代码这里就不提供了。下面假定你已经校验了Range的取值,并得到了 $start 和 $end 两个变量,分别表示开始位置和结束位置。

接下来要做的就是把文件的对应部分的内容发送给浏览器。不过要注意的是,这里涉及到需要发送多个HTTP响应头信息,具体如下:

代码如下:

header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges: bytes');
header("Content-Range: bytes $start-$end/$filesize");
$length = $end - $start + 1;
header("Content-Length: $length");

/ 输出文件的指定部分 /

这里的$length需要注意一下,它的取值是本次传输的内容的长度,而不是整个文件的长度。另外需要注意的一点是,这里的HTTP状态码是206,不是200。

总结

文件下载的断点续传实际上是利用了HTTP协议中对传输部分文件的支持。而HTTP协议的这一特性不仅可以用于实现断点续传,客户端程序也可以利用它来实现多线程下载。

在实现断点续传的过程中,需要注意正确设置各种HTTP头信息。错误的头信息将导致用户下载到的文件损坏,无法使用。

原文链接:http://www.kubiji.cn/juhe-id3146.html

PHP实现文件下载断点续传详解相关推荐

  1. php文件断点续传,PHP实现文件下载断点续传详解

    如果我们的网站提供文件下载的服务,那么通常我们都希望下载可以断点续传(Resumable Download),也就是说用户可以暂停下载,并在未来的某个时间从暂停处继续下载,而不必重新下载整个文件. 通 ...

  2. android文件下载功能实现,Android中DownloadManager实现文件下载实例详解

    Android中DownloadManager实现文件下载 下载 创建下载链接 DownloadManager.Request request = new DownloadManager.Reques ...

  3. Servlet文件下载例子详解及response的contentType类型大全

    一.Servlet文件下载例子. 以下例子为实现文件下载的工具方法, package com.avcon.utils;import java.io.File; import java.io.FileI ...

  4. Servlet文件下载实例详解

    一般浏览器内核不同,通过超链接的方式打开文件不一定会提示下载,如超链接一张图片,浏览器自动解析该图片,而不会提示下载.因此可以将超链接指向服务器Servlet,让Servlet来完成 先写一个静态HT ...

  5. java做jsp问题_java/jsp中 中文问题详解

    java/jsp中 中文问题详解 更新时间:2006年10月13日 00:00:00   作者: 预备知识: 1.字节和unicode Java内核是unicode的,就连class文件也是,但是很多 ...

  6. php 文件扫描去重,PHP中的去重方法详解和文件下载

    本文主要和大家分享PHP中的去重方法详解和文件下载,在php中文件导入过程中,经常会遇到重复事件,那么就需要我们去重,然后进行下载. 1.思想 先设置一个存储主键数组,和一个空数组.解析文件,然后看要 ...

  7. php 断点续传 暂停,PHP 断点续传实例详解

    在做一个案例,要给客户端做断点续传的服务, 断点续传主要是HTTP协议中的Content-Range报头.其理解如下: Content-Range:响应资源的范围.可以在多次请求中标记请求的资源范围, ...

  8. response.setHeader()的用法详解及实现文件下载过程中出现问题的分析

    response.setHeader()用法详解,转载记录: 1. HTTP消息头 (1)通用信息头 即能用于请求消息中,也能用于响应信息中,但与被传输的实体内容没有关系的信息头,如Data,Prag ...

  9. Struts2之struts2文件下载详解

    一.学习案例:通过在downloadfile.jsp页面点击"下载文件",查看文件是否可以成功下载. 二.案例分析:struts2文件下载只需简单配置即可. a)先在下载页面(do ...

最新文章

  1. Windows Server 2003基础与技术指南(2)---Windows Server 2003的安装
  2. 第一篇 献给一次线上100%CPU
  3. 《系统集成项目管理工程师》必背100个知识点-01项目特点
  4. 异步编程异常和死锁处理
  5. HMM——前向后向算法
  6. ArrayList与String[]
  7. php sql desc,PHP SQL 查询封装
  8. Python学习笔记--8.6 函数--递归
  9. Java毕设项目:垃圾分类(带源码和搭建过程)
  10. Rabbitmq的原生javaAPI讲解
  11. JZ5-用两个栈实现队列
  12. mysql connection.h_MySQL connector c++使用笔记
  13. Mina2.0快速入门
  14. easyui ajax post,实例详解EasyUI框架使用Ajax提交注册信息
  15. JAVA调用SO库的示意图
  16. java aspx 验证码,asp 动态生成验证码
  17. ospf多区域的原理和配置实例
  18. 普通本科,一年经验外包直接跳槽阿里?论我是怎么快速晋升的
  19. duet设置_Duet Display使用感受
  20. CHOJ 5202 自然数拆分Lunatic版 【完全背包模型】

热门文章

  1. 高质量的友谊总是发生在两个优秀的独立人格之间
  2. C#泛型简化代码量示例
  3. 揭秘企业级web负载均衡完美架构(转载)
  4. [新功能]团队Blog群发邮件
  5. 对超线程几个不同角度的解释
  6. StringUtils工具类的常用方法
  7. 基于OSS存储搭建Hadoop集群
  8. 在Mybatis3开发中与配置相关的7点体会
  9. Enigma Virtual Box:生成可执行文件。
  10. WPF中对三维模型的控制