使用HTTP范围标头除了字节以外的范围说明符?

Kev*_*son 15 ajax pagination http http-headers

核心问题是关于HTTP标头的使用,包括Range,If-Range,Accept-Ranges和用户定义的范围说明符.

这是一个制作示例,以帮助说明我的问题.假设我有一个Web 2.0样式的应用程序,它显示某种人类可读的文档.这些文档在编辑上分为几页(类似于您在新闻网站上看到的文章).对于此示例,假设:

  • 有一个标题为"HTTP范围问题"的文档分为三页.
  • shell page(/document/shell/http-range-question)知道有关文档的元信息,包括页面数.
  • 在页面onload事件期间通过ajax GET加载文档的第一个可读页面并插入到页面上.
  • 看起来像一个UI控制[1 2 3全部]是在页面的底部,并点击一个号码将显示可读页面(也通过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 Range标头而不是URL的一部分(例如查询字符串参数)吗?在GET /document/content/http-range-question请求上可能是这样的:

Range: page=1
Run Code Online (Sandbox Code Playgroud)

看起来规范只定义字节范围是允许的,所以即使我让我的ajax调用与我的浏览器和服务器代码一起工作,中间的任何东西都可能破坏合同(例如缓存代理服务器).

Range: bytes=0-499
Run Code Online (Sandbox Code Playgroud)

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

更新:我确实找到了一个关于Range标头(在Rest集合中分页)的类似问题,他们提到Dojo的JsonRestStore使用自定义Range标头值.

Range: items=0-24
Run Code Online (Sandbox Code Playgroud)

小智 33

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

来自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
Run Code Online (Sandbox Code Playgroud)

HTTP/1.1定义的唯一范围单位是"字节".HTTP/1.1
实现可以忽略使用其他单元指定的范围.

关键是最后一段.实际上它说的是,当他们为HTTP/1.1编写规范时,他们只概述了"字节"令牌.但是,正如您可以从"其他范围单位"位看到的那样,您可以自由地提出自己的令牌说明符.

使用自己的Range说明符确实意味着您必须控制使用该说明符的客户端和服务器代码.因此,如果您拥有暴露"/ document/content/http-range-question"URI的后端部分,那么您很高兴; 大概你正在使用一个现代的Web框架,它允许你检查进来的请求标头.然后你可以查看Range值来正确执行支持查询.

此外,如果您控制向后端发出请求的AJAX代码,您应该能够自己设置Range标头.

但是,您可能会在自己的问题中预见到一个潜在的缺点:打破缓存的可能性.如果您使用自定义范围单元,则客户端与原始服务器之间的任何缓存"可以忽略使用[字节'以外的单位]"指定的范围.因此,例如,如果您在前端和后端之间有一个Squid/Varnish缓存,则无法保证您希望的结果将从缓存中提供!

您可能还会考虑一种替代实现,而不是使用查询字符串,而是将页面作为URI的"参数"; 例如:/ document/content/http-range-question/page/1.对于服务器端来说,这可能会有一些工作,但它符合HTTP/1.1并且缓存应该正确对待它.

希望这可以帮助.