You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用HTTP 206 Partial Content头部时范围值异常问题排查

解决MP4视频206 Partial Content返回Content-Length不匹配问题

问题根源

你的代码存在两个核心问题,直接导致net::ERR_CONTENT_LENGTH_MISMATCH错误:

  1. 未初始化文件句柄:代码中直接使用$f变量进行fseek和fread操作,但从未通过fopen打开目标文件,导致实际读取的内容长度为0,与设置的Content-Length不匹配。
  2. Range参数校验缺失:未对请求的Range范围做合法性校验,可能出现超出文件大小的非法范围,引发返回内容异常。

修复后的完整代码

<?php
const STORAGE_PATH = '/home/files/';

$filename = "my_video.mp4";
$file = STORAGE_PATH . $filename;

// 检查文件是否存在且可读
if (!file_exists($file) || !is_readable($file)) {
    header("HTTP/1.1 404 Not Found");
    exit("File not found or unreadable");
}

$size = filesize($file);
$begin = 0;
$end = $size - 1;

header('Content-Type: video/mp4');
header('Accept-Ranges: bytes');

// 处理Range请求
if (isset($_SERVER['HTTP_RANGE'])) {
    $range = substr($_SERVER['HTTP_RANGE'], strpos($_SERVER['HTTP_RANGE'], '=') + 1);
    $rangeParts = explode('-', $range);
    
    $begin = intval($rangeParts[0]);
    // 处理无结束值的Range(如bytes=0-)
    $end = isset($rangeParts[1]) && !empty($rangeParts[1]) ? intval($rangeParts[1]) : $size - 1;
    
    // 校验Range合法性,避免越界
    $begin = max(0, min($begin, $size - 1));
    $end = max($begin, min($end, $size - 1));
    
    $length = $end - $begin + 1;
    
    header('HTTP/1.1 206 Partial Content');
    header("Content-Range: bytes $begin-$end/$size");
}

$length = $end - $begin + 1;
header('Content-Length: ' . $length);
header('Content-Disposition: inline; filename="' . $filename . '"');

// 打开文件并定位到起始位置
$f = fopen($file, 'rb');
fseek($f, $begin);

// 分块输出文件内容,避免内存溢出
while ($length > 0) {
    $chunkSize = min(1024 * 1024, $length); // 每次输出1MB
    echo fread($f, $chunkSize);
    $length -= $chunkSize;
    flush();
}

fclose($f);
exit();
?>

关键修复点说明

  • 文件存在性检查:先验证文件是否存在且可读,避免后续操作报错。
  • 初始化文件句柄:通过fopen($file, 'rb')以二进制只读模式打开文件,确保能正确读取内容。
  • Range合法性校验:强制将$begin和$end限制在合法范围内,防止请求超出文件大小的范围。
  • 分块输出内容:大文件直接fread可能导致内存溢出,分块输出更稳定。
  • 清理冗余代码:移除重复的$length计算,逻辑更清晰。

错误触发原因解释

当浏览器发送Range: bytes=0-请求时,你的代码虽然计算了正确的Content-Length,但由于未打开文件,fread($f, $length)返回空内容,实际输出的内容长度为0,与头部声明的Content-Length不一致,浏览器因此抛出net::ERR_CONTENT_LENGTH_MISMATCH错误。

内容的提问来源于stack exchange,提问作者Phaelax

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 19:39:27