標籤:206、http報文、報文結構、報文編碼、範圍請求
HTTP報文內的HTTP資訊
HTTP通訊過程包括從用戶端發往伺服器的請求及從伺服器端返回用戶端的響應。此篇就具體瞭解下請求和響應怎麼運作的。
3.1 HTTP報文
用於HTTP協議互動的資訊被稱為HTTP報文。請求端(用戶端)的HTTP報文叫做請求報文,響應端(伺服器端)的叫做響應報文。HTTP報文本身是由多行(用CR+LF做分行符號)資料構成的字串文本。
HTTP報文大致可分為報文首部和報文主題兩部分。兩者由最初出現的空行(CR+LF)來劃分。通常,並不一定要有報文主體。
650) this.width=650;" src="http://s4.51cto.com/wyfs02/M00/89/64/wKioL1gRxFCh9dcYAABu0TEIBu4783.png-wh_500x0-wm_3-wmp_4-s_2565922699.png" title="03-01.png" alt="wKioL1gRxFCh9dcYAABu0TEIBu4783.png-wh_50" />
3.2 請求報文及響應報文的結構
請求報文和響應報文的結構:
650) this.width=650;" src="http://s3.51cto.com/wyfs02/M02/89/64/wKioL1gRxiPjMB45AAFaON7rx2Q395.png-wh_500x0-wm_3-wmp_4-s_2704182927.png" title="03-02.png" alt="wKioL1gRxiPjMB45AAFaON7rx2Q395.png-wh_50" />
請求報文和響應報文的執行個體如下:
GET / HTTP/1.1 請求行 Host:hackr.jp 各種首部欄位 User-Agent:Mozilla/5.0(Windows NT 6.1;XXX) Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*,q=0.8 Accept-Langeuage:ja,en-us,q=0.7,en;q=03 Accept-Encoding:gzip,default DNT:1 Connection:keep-alive Pragma:no-cache Cache-control:no-cache HTTP/1.1 200 OK 狀態行 Date:Fri ,13 Jul 2012 02:45:26 GMT Server:Apache Last-Modified:Fri ,31 Aug 2007 02:02:20 GMT ETag:"45bael-16a-46d776ac" Accept-Ranges:bytes Content-Length:362 Connection:close Content-Type:text/html 各種首部欄位 空行(CR+LF) <html> 報文主體 ... </html>
請求報文和響應報文的首部內容由以下資料群組成。現在詳細講解出現的各種首部欄位及狀態代碼。
請求行:包含用於請求的方法,請求URI和HTTP版本。
狀態行:包含表明響應結構的狀態代碼,原因短語和HTTP版本。
首部欄位:包含表示請求或者響應的各種條件和屬性的各類首部。一般首部分為通用首部、請求首部、響應首部和實體首部四種。
其他:可能包含HTTP的RFC裡未定義的首部(Cookie等)
3.3 編碼提升傳輸速率
HTTP在傳輸資料時可以按照資料原貌直接傳輸,但也可以在傳輸過程中通過編碼來提升傳輸速率。通過在傳輸時編碼,能有效地處理大量的訪問請求。但是編碼的操作需要電腦來完成,因此會消耗更多的CPU等資源。
3.3.1 報文主體和實體主體的差異
·報文(message)
是HTTP通訊的基本單位,由8位組位元組流組成(Octet sequence,其中octet為8個位元),通過HTTP通訊傳輸。
·實體(entity)
作為請求或響應的有效載荷資料(補充項)被傳輸,其內容有實體 首部和實體主體組成。
HTTP報文的主體用於傳輸請求或響應的實體主體。
通常,報文主體等於實體主體。只有當傳輸過程中進行編碼操作時,實體主體內容發生變化,才導致它和報文主體產生差異。
3.3.2 壓縮傳輸的內容編碼
向待發送郵件內增加附件時,為了使郵件容量變小,我們先會用ZIP壓縮檔之後再添加附件發送。HTTP協議中有一種被稱為內容編碼的功能也能進行類似的操作。內容編碼指明應用在實體內容上的編碼格式,並保持實體資訊原樣壓縮。內容編碼後的實體由用戶端接收並負責解碼。
常見的內容編碼有以下幾種:
·GZIP(GUN zip)
·compress(Unix系統的標準壓縮)
·deflate(zlib)
·identity(不進行編碼)
3.3.3分隔發送的分塊傳輸編碼
在HTTP通訊過程中,請求的編碼實體資源尚未全部傳輸完成之前,瀏覽器無法顯示請求頁面。在傳輸大容量資料時,通過把資料分隔成多塊,能夠讓瀏覽器逐步顯示頁面。這種把實體主體分塊的功能稱為分塊傳輸編碼(Chunked Transfer Coding)。
分塊傳輸編碼會將實體主體分成多個部分(塊)。每一塊都會用十六進位來標記塊的大小,而實體主體的最後一塊會使用"0(CR+LF)"來標記。使用分塊傳輸編碼的實體主體會由接收的用戶端負責解碼,恢複到編碼前的實體主體。HTTP/1.1中存在一種稱為傳輸編碼的機制,它可以在通訊時按某種編碼方式傳輸,但只定義作用於分塊傳輸編碼中。
650) this.width=650;" src="http://s5.51cto.com/wyfs02/M02/89/67/wKiom1gR0FfCPSBNAACtEY4wdo4403.png-wh_500x0-wm_3-wmp_4-s_498878906.png" title="03-03.png" alt="wKiom1gR0FfCPSBNAACtEY4wdo4403.png-wh_50" />
3.4 發送多種資料的多部分對象集合
發送郵件時,我們可以在郵件裡寫入文字並添加多份附件。這是因為採用了MIME(Multipurpose Internet Mail Extensions,多用途網際網路郵件擴充)機制,它允許郵件處理文本、圖片、視頻等多個不同類型的資料。例如,圖片等位元據以ASCII碼字串編碼方式指明,就是利用MIME來描述標記資料類型。而在MIME擴充中會使用一種稱為多部分對象集合(Multipart)的方法,來容納多份不同類型的資料。
相應的,HTTP協議中也採納了多部分對象集合,發送的一份報文主體內科含有多類型實體。通常是在圖片或者文字檔上傳時使用。
多部分對象集合包含的對象如下:
multipart/form-data 在Web表單檔案上傳時使用。
multipart/byteranges 狀態代碼206(Partial Content,部分內容)響應報文包含了多個範圍的內容.
multipart/form-data Content-Type:multipart/form-data;boundary=AaB03x-- Content-Disposition:form-data;name="field1" Joe Blow --AaB03x Content-Disposition:form-data;name="pics";filename="file1.txt" Content-Type:text/plain ...(file1.txt的資料)... --AaB03x-- multipart/byteranges HTTP/1.1 206 Partial Content Date:Fri ,13 Jul 2012 02:45:26 GMT Last-Modified:Fri ,31 Aug 2007 02:02:20 GMT Content-Type:multipart/byteranges;boundary=THIS_STRING_SEPARATES --THIS_STRING_SEPARATES Content-Type:application/pdf Content-Range:bytes 500-999/8000 ...(範圍指定的資料)... --THIS_STRING_SEPARATES Content-Type:application/pdf Content-Range:bytes 7000-7999/8000 ...(範圍指定的資料)... --THIS_STRING_SEPARATES--
在HTTP報文中使用多部分對象集合時,需要在首部欄位裡加上Content-Type。待會詳細介紹Content-Type這個首部欄位。
使用boundary字串來劃分多部分對象集合指明的各類實體。在boundary字串指定的各個實體的起始行之前插入"--"標記(例如--AaB03x、--THIS_STRING_SEPARATES),而在多部分對象稽核對應的字串的最後插入"--"標記(例如--AaB03x--、--THIS_STRING_SEPARATES--)作為結束。
多部分對象集合的每個部分類型中,都可以含有首部欄位。另外,可以在某個部分中嵌套使用多部分對象集合。
3.5 擷取部分內容的範圍請求
以前,使用者不能使用現在這種高速的頻寬訪問互連網,當時,下載一個尺寸稍大的圖片或檔案就非常吃力。如果下載過程中遇到網路中斷的情況,那必須重頭開始,為瞭解決上述問題,需要一種可恢複的機制。所謂恢複是只能從之前下載中斷處恢複下載。
針對範圍請求,響應狀態代碼為206 Partial Content的響應報文。另外,對於多重範圍的範圍請求,響應會在首部欄位Content-Type表明multipart/bytesranges後響應報文。如果伺服器無法響應範圍請求,則會返回狀態代碼200 OK和完整的實體內容。
要實現該功能需要指定下載的實體範圍。像這樣,指定範圍發送的請求叫做範圍請求(Range Request).執行範圍請求時,會使用到首部欄位Range來指定資源的byte範圍。byte範圍的指定形式如下:
3.5.1 5001-10 000 位元組
Range:bytes=5001-10000
3.5.2 從5001位元組之後全部的
Range:bytes=5001-
3.5.3 從一開始到3000位元組和5000-7000位元組的多重範圍
Range:bytes=-3000,5000-7000
具體擷取部分內容的請求執行個體如下:
650) this.width=650;" src="http://s1.51cto.com/wyfs02/M01/89/65/wKioL1gR2iHRNb-lAADtZbwbtSc661.png-wh_500x0-wm_3-wmp_4-s_1011690427.png" title="03-04.png" alt="wKioL1gR2iHRNb-lAADtZbwbtSc661.png-wh_50" />
3.6 內容協商返回最合適的內容
同一個Web網站有可能存在著多份相同內容的頁面,比如英語班和中文版的Web頁面,他們內容上雖然相同,但是使用的語言卻不同。當瀏覽器的預設語言為英語或者中文,訪問相同URI的Web頁面時,則會顯示對應的英語或中文版的Web頁面。這樣的機制稱為內容協商(Content Negotiation)。
內容協商機制是指用戶端和伺服器端就響應的資源內容進行交涉,然後提供給用戶端最為合適的資源。內容協商會以響應資源的語言、字元集、編碼方式等作為判斷基準。
包含在請求報文中的某些首部欄位(如下)就是判斷的基準。下一章將會仔細講解這些首部欄位的含義:
·Accept
·Accept-Charset
·Accept-Encoding
·Accept-Language
·Content-Language
內容協商技術分為伺服器驅動協商、用戶端驅動協商和透明協商三種
3.6.1 伺服器驅動協商(Server-driven Negotiation)
由伺服器進行內容協商。以請求的首部欄位為參考在伺服器端自動處理。但對使用者來說,以瀏覽器發送的資訊作為判定的依據,並不一定能篩選出最優內容。
3.6.2 用戶端驅動協商(Agent-driven Negotiation)
由用戶端進行內容協商。使用者從瀏覽器顯示的可選項列表中手動選擇。還可以利用JavaScript指令碼在Web頁面上自動進行上述選擇。比如按照OS的類型或者瀏覽器類型,自行切換成PC版頁面或手機版頁面。
3.6.3 透明協商(Transparent Negotiation)
是伺服器驅動和用戶端驅動的結合體,是由伺服器端和用戶端各自進行內容協商的一種方法。
讀《圖解HTTP》總結--第三章