2009-09-16 69 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