在Chrome浏览器中PHP下载简历时,HTTP RANGE无法正常工作

5
我正在使用以下代码,并进行了适应:http://ee.php.net/manual/en/function.fread.php#84115,以允许下载恢复,在Firefox上运行良好,但在Chrome上根本不起作用。如果我在Chrome中尝试,文件会下载,我将其暂停,等待几分钟,但然后当我恢复下载时,下载立即完成并且文件已损坏。
有什么想法吗?
function dl_file_resumable($file, $is_resume=TRUE)
{
    //First, see if the file exists
    if (!is_file($file))
    {
        die("<b>404 File not found!</b>");
    }

    //Gather relevent info about file
    $size = filesize($file);
    $fileinfo = pathinfo($file);

    //workaround for IE filename bug with multiple periods / multiple dots in filename
    //that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
    $filename = (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')) ?
                  preg_replace('/\./', '%2e', $fileinfo['basename'], substr_count($fileinfo['basename'], '.') - 1) :
                  $fileinfo['basename'];

    $file_extension = strtolower($path_info['extension']);

    $ctype='application/octet-stream';

    //check if http_range is sent by browser (or download manager)
    if($is_resume && isset($_SERVER['HTTP_RANGE']))
    {
        list($size_unit, $range_orig) = explode('=', $_SERVER['HTTP_RANGE'], 2);

        if ($size_unit == 'bytes')
        {
            //multiple ranges could be specified at the same time, but for simplicity only serve the first range
            //http://tools.ietf.org/id/draft-ietf-http-range-retrieval-00.txt
            list($range, $extra_ranges) = explode(',', $range_orig, 2);
        }
        else
        {
            $range = '';
        }
    }
    else
    {
        $range = '';
    }

    //figure out download piece from range (if set)
    list($seek_start, $seek_end) = explode('-', $range, 2);

    //set start and end based on range (if set), else set defaults
    //also check for invalid ranges.
    $seek_end = (empty($seek_end)) ? ($size - 1) : min(abs(intval($seek_end)),($size - 1));
    $seek_start = (empty($seek_start) || $seek_end < abs(intval($seek_start))) ? 0 : max(abs(intval($seek_start)),0);

    //add headers if resumable
    if ($is_resume)
    {
        //Only send partial content header if downloading a piece of the file (IE workaround)
        if ($seek_start > 0 || $seek_end < ($size - 1))
        {
            header('HTTP/1.1 206 Partial Content');
        }

        header('Accept-Ranges: bytes');
        header('Content-Range: bytes '.$seek_start.'-'.$seek_end.'/'.$size);
    }

    //headers for IE Bugs (is this necessary?)
    //header("Cache-Control: cache, must-revalidate");   
    //header("Pragma: public");

    header('Content-Type: ' . $ctype);
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    header('Content-Length: '.($seek_end - $seek_start + 1));

    //open the file
    $fp = fopen($file, 'rb');
    //seek to start of missing part
    fseek($fp, $seek_start);

    //start buffered download
    while(!feof($fp))
    {
        //reset time limit for big files
        set_time_limit(0);
        print(fread($fp, 1024*8));
        flush();
        ob_flush();
    }

    fclose($fp);
    exit;
}

dl_file_resumable('/home/var/www/app/back/media/ready/5a58hGuRFR.tar');

这里没有足够的示例来展示如何做到这一点吗? - yergo
你没有包含完整的脚本,你有可能以 ?> 结束了脚本吗? - Professor of programming
另外,您使用的是哪种Web服务器软件? - Professor of programming
@Bonner,是的,我的脚本最后有一个 ?>。我在Debian 7上运行Apache作为Web服务器。 - Mokkun
从脚本末尾删除 ?>,看看是否可以解决问题。 - Professor of programming
1个回答

1
我没有尝试执行您的代码,但看起来switch语句有些混乱:
  1. 它没有任何意义 - 如果$ext被设置了,它将落入唯一的default部分
  2. 它的语法错误 - 在default后应该是:
  3. 它有一个未在任何地方设置的变量$new_name
最终,在回复中出现这些错误,不同的浏览器会以不同的方式处理它们。

更进一步 - 我完全看不出 switch 语句的意义。 - sitilge
嗨,我使用完整的功能和一些修改更新了我的代码,我删除了内容类型的开关部分,因为我想强制下载,所以我总是使用“application/octet-stream”。 - Mokkun
@Mokkun,这意味着它对你有效吗?我尝试了一些大约180MB的zip文件,在我的Chrome 43.0.2357.124 m上可以工作。+我在while(!feof($fp))循环结束时添加了usleep(100);来模拟网络速度。它也适用于Firefox,Opera。IE不允许停止(按钮被禁用),但是Safari for Windows在停止后会从头开始恢复下载。 - Pilskalns
@Pilskalns 对我来说,在Firefox上它可以工作(暂停下载一个小时后恢复),但在Chrome上不行,当我在大约30分钟后恢复下载时,它会显示下载已完成并且文件损坏了(无法从停止的地方继续)。至于网络速度,您可以只更改print(fread($fp, 1024*8));部分。 - Mokkun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接