正如Wrikken 建议的那样,这是一个有效的请求。当客户端请求媒体或恢复下载时,这也很常见。
客户端通常会测试服务器是否处理范围请求,而不仅仅是寻找Accept-Ranges 响应。 Chrome总是会发送Range: bytes=0- 与它对视频的第一个 GET 请求,所以你不能忽略它。
每当客户端在其请求中包含 Range: 时,即使它的格式不正确,它也会期待部分内容 (206) 响应。在 HTML5 视频播放期间向前搜索时,浏览器只请求起点。例如:
Range: bytes=3744-
因此,为了让客户端正确播放视频,您的服务器必须能够处理这些不完整的范围请求。
您可以通过两种方式处理您在问题中指定的“范围”类型:
首先,您可以使用响应中给出的请求起点进行回复,然后是文件的总长度减一(请求的字节范围为零索引)。例如:
请求:
GET /BigBuckBunny_320x180.mp4
Range: bytes=100-
回复:
206 Partial Content
Content-Type: video/mp4
Content-Length: 64656927
Accept-Ranges: bytes
Content-Range: bytes 100-64656926/64656927
其次,您可以回复请求中给出的起点和开放式文件长度(大小)。这适用于总长度未知的网络广播或其他媒体。例如:
请求:
GET /BigBuckBunny_320x180.mp4
Range: bytes=100-
回复:
206 Partial Content
Content-Type: video/mp4
Content-Length: 64656927
Accept-Ranges: bytes
Content-Range: bytes 100-64656926/*
提示:
您必须始终使用范围中包含的内容长度进行响应。如果范围是完整的,从头到尾,那么内容长度就是差异:
请求:
范围:字节=500-1000
回应:
内容范围:字节 500-1000/123456
请记住,范围是从零开始的,所以Range: bytes=0-999 实际上请求的是 1000 个字节,而不是 999,因此请使用以下内容进行响应:
Content-Length: 1000
Content-Range: bytes 0-999/123456
或者:
Content-Length: 1000
Content-Range: bytes 0-999/*
但是,如果可能,请避免使用后一种方法,因为一些媒体播放器会尝试从文件大小中计算出持续时间。如果您的请求是针对媒体内容的,这是我的预感,那么您应该在响应中包含其持续时间。这是通过以下格式完成的:
X-Content-Duration: 63.23
这必须是一个浮点数。与Content-Length 不同,此值不必准确。它用于帮助播放器在视频中搜索。如果您正在流式传输网络广播,并且只知道它会持续多长时间,那么最好包括您的估计持续时间,而不是完全忽略它。因此,对于两个小时的网络广播,您可以包括以下内容:
X-Content-Duration: 7200.00
对于某些媒体类型,例如 webm,您还必须包含 content-type,例如:
Content-Type: video/webm
所有这些都是媒体正常播放所必需的,尤其是在 HTML5 中。如果您不提供持续时间,播放器可能会尝试从文件大小中计算出持续时间(以允许搜索),但这并不准确。这很好,对于网络广播或实时流媒体来说是必要的,但对于视频文件的播放来说并不理想。您可以使用 FFMPEG 等软件提取持续时间并将其保存在数据库中,甚至保存在文件名中。
X-Content-Duration 正在逐步淘汰,取而代之的是Content-Duration,所以我也将其包括在内。对“0-”请求的基本响应至少包括以下内容:
HTTP/1.1 206 Partial Content
Date: Sun, 08 May 2013 06:37:54 GMT
Server: Apache/2.0.52 (Red Hat)
Accept-Ranges: bytes
Content-Length: 3980
Content-Range: bytes 0-3979/3980
Content-Type: video/webm
X-Content-Duration: 2054.53
Content-Duration: 2054.53
还有一点:Chrome 总是以以下方式开始其第一个视频请求:
Range: bytes=0-
某些服务器会发送常规的 200 响应作为回复,它会接受(但播放选项有限),但尝试发送 206 来代替显示您的服务器处理范围。 RFC 2616 表示忽略范围标题是可以接受的。