html5 video. http,html - HTML5 video and partial range HTTP requests - Stack Overflow

这段代码展示了一个PHP类`Model_DownloadableFile`,用于处理浏览器中的文件下载,特别是支持断点续传。它检查文件是否存在,读取HTTP请求头中的`Range`来确定是否需要部分下载,并发送适当的内容范围、类型和长度头。如果请求了部分文件,它将从指定的开始位置读取并发送数据。否则,将发送整个文件。
摘要由CSDN通过智能技术生成

I know this is an old question, but if it helps you can try the following "Model" that we use in our code base.

class Model_DownloadableFile {

private $full_path;

function __construct($full_path) {

$this->full_path = $full_path;

}

public function get_full_path() {

return $this->full_path;

}

// Function borrowed from (been cleaned up and modified slightly): http://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file/4451376#4451376

// Allows for resuming paused downloads etc

public function download_file_in_browser() {

// Avoid sending unexpected errors to the client - we should be serving a file,

// we don't want to corrupt the data we send

@error_reporting(0);

// Make sure the files exists, otherwise we are wasting our time

if (!file_exists($this->full_path)) {

header('HTTP/1.1 404 Not Found');

exit;

}

// Get the 'Range' header if one was sent

if (isset($_SERVER['HTTP_RANGE'])) {

$range = $_SERVER['HTTP_RANGE']; // IIS/Some Apache versions

} else if ($apache = apache_request_headers()) { // Try Apache again

$headers = array();

foreach ($apache as $header => $val) {

$headers[strtolower($header)] = $val;

}

if (isset($headers['range'])) {

$range = $headers['range'];

} else {

$range = false; // We can't get the header/there isn't one set

}

} else {

$range = false; // We can't get the header/there isn't one set

}

// Get the data range requested (if any)

$filesize = filesize($this->full_path);

$length = $filesize;

if ($range) {

$partial = true;

list($param, $range) = explode('=', $range);

if (strtolower(trim($param)) != 'bytes') { // Bad request - range unit is not 'bytes'

header("HTTP/1.1 400 Invalid Request");

exit;

}

$range = explode(',', $range);

$range = explode('-', $range[0]); // We only deal with the first requested range

if (count($range) != 2) { // Bad request - 'bytes' parameter is not valid

header("HTTP/1.1 400 Invalid Request");

exit;

}

if ($range[0] === '') { // First number missing, return last $range[1] bytes

$end = $filesize - 1;

$start = $end - intval($range[0]);

} else if ($range[1] === '') { // Second number missing, return from byte $range[0] to end

$start = intval($range[0]);

$end = $filesize - 1;

} else { // Both numbers present, return specific range

$start = intval($range[0]);

$end = intval($range[1]);

if ($end >= $filesize || (!$start && (!$end || $end == ($filesize - 1)))) {

$partial = false;

} // Invalid range/whole file specified, return whole file

}

$length = $end - $start + 1;

} else {

$partial = false; // No range requested

}

// Determine the content type

$finfo = finfo_open(FILEINFO_MIME_TYPE);

$contenttype = finfo_file($finfo, $this->full_path);

finfo_close($finfo);

// Send standard headers

header("Content-Type: $contenttype");

header("Content-Length: $length");

header('Content-Disposition: attachment; filename="' . basename($this->full_path) . '"');

header('Accept-Ranges: bytes');

// if requested, send extra headers and part of file...

if ($partial) {

header('HTTP/1.1 206 Partial Content');

header("Content-Range: bytes $start-$end/$filesize");

if (!$fp = fopen($this->full_path, 'r')) { // Error out if we can't read the file

header("HTTP/1.1 500 Internal Server Error");

exit;

}

if ($start) {

fseek($fp, $start);

}

while ($length) { // Read in blocks of 8KB so we don't chew up memory on the server

$read = ($length > 8192) ? 8192 : $length;

$length -= $read;

print(fread($fp, $read));

}

fclose($fp);

} else {

readfile($this->full_path); // ...otherwise just send the whole file

}

// Exit here to avoid accidentally sending extra content on the end of the file

exit;

}

}

You then use it like this:

(new Model_DownloadableFile('FULL/PATH/TO/FILE'))->download_file_in_browser();

It will deal with sending part of the file or the full file etc and works well for us in this and lots of other situations. Hope it helps.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值