2009-09-16 32 views
15

核心问题是关于使用HTTP头,包括RangeIf-Range,Accept-Ranges和用户定义的范围说明符。使用带范围说明符而不是字节的HTTP范围标题?

这里是一个制造的例子来帮助说明我的问题。假设我有一个Web 2.0风格的应用程序,它显示某种人类可读的文档。这些文件编辑分成多个页面(类似于您在新闻网站上看到的文章)。对于这个例子,假设:

  • 有一个标题为“HTTP范围问题”的文档分成三页。
  • shell页面(/document/shell/http-range-question)知道关于文档的元信息,包括页面的数量。
  • 文档的第一个可读页面在页面onload事件期间通过ajax GET加载并插入页面。
  • 看起来像[1 2 3所有]的UI控件位于页面底部,单击某个数字将显示该可读页面(也通过ajax加载),然后单击“全部”将显示整个文件。假定这些URL的1,2,3和所有的用例:
    • /document/content/http-range-question?page=1
    • /document/content/http-range-question?page=2
    • /document/content/http-range-question?page=3
    • /document/content/http-range-question

我们的问题。我可以使用HTTP范围标头而不是URL的一部分(例如查询字符串参数)吗?也许是这样的GET /document/content/http-range-question要求:

Range: page=1 

它看起来像规范只定义字节范围为可以容许的,所以即使我做了我的Ajax调用与我的浏览器和服务器代码的工作,中间什么事情都可能打破合同(如缓存代理服务器)。

Range: bytes=0-499 

自定义范围说明符的任何意见或现实世界的例子?

更新:我没有找到有关范围的报头(Paging in a Rest Collection),他们提到,Dojo的JsonRestStore使用自定义的范围标头值过类似的问题。

Range: items=0-24 
+0

[Paging in Rest Collection]的可能重复(http://stackoverflow.com/questions/924472/paging-in-a-rest-collection) – DanMan 2015-09-20 09:44:23

+0

@DanMan - 我已经链接到类似的问题,但并非所有的HTTP都是REST,这会问一个关于允许值的问题,而不是REST语义。此外,不同的问题标题措辞有助于不同的人找到他们的答案。 – 2015-09-20 22:18:19

回答

32

绝对 - 您可以自由指定您喜欢的任何范围单位。

从RFC 2616:

3.12范围单位

HTTP/1.1允许客户端请求 ,只有部分(的范围)的
响应实体被包括在 响应内。 HTTP/1.1使用范围(部分14.35)和 内容范围(部分14.16)
标头字段中的范围单元 。一个实体可以根据 各种结构单位划分为子域。

range-unit  = bytes-unit | other-range-unit 
    bytes-unit  = "bytes" 
    other-range-unit = token 

唯一范围由 HTTP定义/ 1.1单位为 “字节”。 HTTP/1.1
实现可以忽略使用其他单位指定的范围 。

关键是最后一段。真正的意思是,当他们为HTTP/1.1编写规范时,他们只概述了“字节”标记。但是,正如你从'其他范围单位'中看到的那样,你可以自由地想出你自己的令牌说明符。

用你自己的Range指定符来表示你必须控制使用该指定符的客户端和服务器代码。所以,如果你拥有公开“/ document/content/http-range-question”URI的后端部分,那么你很好,大概你正在使用一个现代的web框架,让你检查请求头文件。然后,你可以查看Range值来正确执行支持查询。此外,如果您控制向后端发出请求的AJAX代码,则应该可以自行设置Range标头。

但是,您预计在您的问题中存在潜在的不足之处:可能会打破缓存。如果您使用的是自定义的Range单元,则客户端和原始服务器之间的任何缓存“可以忽略使用[字节'以外的单位]指定的范围”。例如,如果您在前端和后端之间有Squid/Varnish缓存,则不能保证您希望的结果将从缓存中提供!

你也可以考虑一个替代实现,它不是使用查询字符串,而是使页面成为URI的“参数”;例如:/ document/content/http-range-question/page/1。这对服务器端来说可能会多一点工作,但它符合HTTP/1.1并且缓存应该正确处理它。

希望这会有所帮助。

+0

缓存的好处,但这是“变化”标题的用途。 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44更大的问题是它不是非常好的HATEOAS。 – 2014-06-26 02:23:48

-2

这听起来像你想要改变HTTP规范只是删除查询字符串参数。为了做到这一点,你必须修改客户端上的代码,以发送修改后的头文件和服务器,从“Range”头文件而不是查询字符串中读取。

最终的结果是,这可能会工作,但你打破了所有的标准和现有的工具来做到这一点。

+4

我认为它更多的是坚持规范的精神,因为一个URL可以获得整个内容,或者使用规范中定义的头部可以获取内容的逻辑部分(但不是按字节分割)。但是,即使我能够实现它,这也是一个糟糕的主意。 – 2009-09-16 18:31:54

+3

我同意Kevin的观点,我认为这个规范很清楚,这是可能的(为什么其他的应该有一个Accept-Ranges字段在指定服务器接受的范围单元的响应中)。另外,当返回例如一个JSON数组集合,Content-Range响应可以给出所有项目的大小,例如Content-Range:项目0-9/20,而查询字符串解决方案必须以某种方式将该信息转移到其他地方。 – Daff 2011-03-02 23:35:11

0

HTTP范围通常用于恢复中断下载而不从头开始。

你想要做的事情可以通过OAI-ORE更好地处理,它允许你定义多个文档之间的关系。 (替代格式,整体组件等)

不幸的是,这是一种相对较新的元数据格式,我不知道任何带有本地支持的网页浏览器。

0

字节是HTTP 1.1规范支持的唯一单位。

+2

是的,但新的范围单位是一个扩展点 – 2013-03-25 12:51:32

+0

新的范围单位必须在https://tools.ietf.org/html/rfc7233#section-2.2中提到的“范围单位注册表”中进行注册如果没有正式注册任何其他字节单位或“无”是无效的。 – 2016-07-12 18:57:42

+0

从7233开始:“新范围单元*应*向IANA注册。” (重点是我的)。 “应该”未在中定义。如果这是一项要求,即使是软性要求,他们是否也不会用“必须”,“需要”,“应该”,“应该”或“推荐”之一表示? – 2016-07-25 19:44:59