Range
标头如何与Content Negotiation一起使用?让我解释一下,但首先让我们都同意以下几点:HTTP 是一种无状态协议。
当 HTTP 服务器能够发送单个资源的多个表示时,内容协商用于确定要发送的表示:客户端可能会指示其偏好(即英语和 GIF),然后服务器将遵守或 - 在以下情况下它不能——服务器会通过一些启发式评估来选择发送给客户端的表示。
到目前为止一切都很好......但是当你投入其中时会发生什么Range
?
想象以下场景:
John 在巴黎的一个机场,他的浏览器发送一个 HTTP 请求。出于某种原因,他的浏览器没有显示任何内容类型、语言或压缩方面的偏好。
GET /uri HTTP/1.1 Host: example.com
由于它几乎没有经过,服务器通过一些启发式方法,决定发送 URI 的法语表示(IP 被识别为来自法国。)
200 Okay Accept-Ranges: bytes Content: text/html Content-Language: fr ....data...
在传输过程中,John 停止下载以赶上他的航班。约翰一到纽约就恢复下载。
GET /uri HTTP/1.1 Host: example.com Range: 2000-3000
同样,在客户端偏好信息很少的情况下,服务器这次决定发送 URI 的英文表示(IP 被识别为来自纽约。)
至此,该文件已损坏,因为它的一部分是法语,另一部分是英语。
推测:
- 客户端可能会记住第一个响应中的内容类型和语言,以便将该信息发送回服务器以用于第二个请求(在 下
Accept: text/html Accept-Language: fr
)。但是,由于RFC2616和RFC7233都对此进行了说明(甚至不是建议),我相信具有这种行为的 HTTP 客户端很少见……但我还没有对其进行测试。
笔记:
- 在上面的场景中,我们可以很容易地让客户端发送首选项并让服务器无法遵守......并且仍然回退到其他启发式方法。问题仍然存在。
- 作为另一个例子,这个问题也存在于另一个 SO 问题中:Sample http range request session
TL;博士
GET /uri HTTP/1.1
Host: example.com
Accept: text/html; q=1.0, text/plain; q=0.8, */*; q=0.1
Accept-Language: en; q=1.0, */*; q=0.1
Range: 100-200
在上面,范围适用于所请求资源的哪种表示?!