我正在阅读http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35, 并试图弄清楚如何继续文件下载。
例如,假设一个文件的长度为100个字节,而我拥有所有100个字节。但是,我不知道预期的文件大小应该是多少,所以我要文件并指定一个看起来像这样的Range标头:
Range: bytes=100-
这是有效的范围请求吗?
我正在阅读http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35, 并试图弄清楚如何继续文件下载。
例如,假设一个文件的长度为100个字节,而我拥有所有100个字节。但是,我不知道预期的文件大小应该是多少,所以我要文件并指定一个看起来像这样的Range标头:
Range: bytes=100-
这是有效的范围请求吗?
Answers:
这是语法上有效的请求,但不是可满足的请求。如果您在该部分中进一步查看,则会看到:
如果在语法上有效的字节范围集包括至少一个字节范围规范,且其第一个字节位置小于实体主体的当前长度,则至少一个后缀字节范围规范具有非-后缀长度为零,则可满足字节范围设置。否则,字节范围设置将无法满足。如果字节范围设置不令人满意,则服务器应返回状态为416的响应(请求范围不令人满意)。否则,服务器应该返回状态206(部分内容)的响应,其中包含实体主体的可满足范围。
因此,我认为在您的示例中,服务器应返回416,因为它不是该文件的有效字节范围。
正如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: 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表示可以忽略范围标头。
与Mark Novakowski的答案相反,由于某些原因,答案被很多人支持,是的,这是一个有效且可满足的请求。
实际上,正如Wrikken指出的那样,该标准就是一个例子。在实践中,Firefox会按预期方式(使用206代码)响应此类请求,而这正是我用来实现渐进式下载的方式,即,仅获得长日志文件的尾部,该日志文件随轮询而实时增长。
对于在2019年绊倒Victor Stoddard的上述答案并变得充满希望和关注的人们,请注意:
a)在Firefox 41中删除了对X-Content-Duration的支持:https : //developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/41#HTTP
b)我认为Firefox仅支持.ogg音频和.ogv视频,而不支持其他任何类型。
c)我看不到Chrome曾经完全支持它,但这可能只是我缺乏研究。但是,到目前为止,对于Chrome浏览器71中的webm或ogv视频,它的存在与否似乎没有任何影响。
d)我找不到“ Content-Duration”替换为“ X-Content-Duration”的任何地方,我认为“ X-Content-Duration”没有生存足够长的时间来提供后继标头名称。
我认为这意味着,从今天开始,如果您要向Webm或ogv容器提供包含不知道其持续时间(例如ffpeg管道输出)的流到Chrome或FF的流,并且希望它们可在HTML 5视频元素,您可能不走运。无论您是否通过范围请求进行服务,Firefox 64.0都竭尽全力地使这些可擦写的内容变得可疑,但如果您查找的次数超出其认为合适的次数,它就会感到困惑并抛出混乱,直到流被完全下载为止。Chrome甚至不会尝试,它只会停止工作,直到整个流播放完毕后,您才可以彻底擦洗。