超文本傳輸協定(HTTP,HyperText Transfer Protocol)是網際網路上應用最為廣泛的一種網絡協定。所有的WWW檔案都必須遵守這個标準。設計HTTP最初的目的是為了提供一種釋出和接收HTML頁面的方法。
HTTP協定的主要特點
- 支援客戶/伺服器模式。
- 簡單快速:客戶向伺服器請求服務時,隻需傳送請求方法和路徑。
- 靈活:HTTP允許傳輸任意類型的資料對象。正在傳輸的類型由Content-Type加以标記。
- 無連接配接:無連接配接的含義是限制每次連接配接隻處理一個請求。伺服器處理完客戶的請求,并收到客戶的應答後,即斷開連接配接。采用這種方式可以節省傳輸時間。
- 無狀态:HTTP協定是無狀态協定。無狀态是指協定對于事務處理沒有記憶能力。缺少狀态意味着如果後續處理需要前面的資訊,則它必須重傳,這樣可能導緻每次連接配接傳送的資料量增大。另一方面,在伺服器不需要先前資訊時它的應答就較快。
HTTP封包組成部分
- 對封包進行描述的起始行(start line)
- 包含屬性首部(header)
- 包含資料的主體(body)
HTTP/1.0 OK //起始行
Content-type:text/plain //首部
Content-length:19 //首部
Hi I'm a message! 主體
HTTP封包文法
所有的封包都可以分為下面兩類:
1. 請求封包(request message)
2. 響應封包(response message)
在HTTP請求中:
第一行必須是一個請求行(request line),用來說明請求類型、要通路的資源以及使用的HTTP版本。
在首部之後是一個空行,再此之後可以添加任意的其他資料[稱之為主體(body)]。
例如下圖:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISOyUTM1QDM2EDMyITM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
//一個請求行(request line)
GET /liuxinmingcode HTTP/1.1
//第一個首部,HOST,結合HOST和上一行中的斜杠(/),可以通知伺服器請求的是blog.csdn.net/liuxinmingcode(HTTP 1.1才需要使用首部HOST,而原來的1.0版本則不需要使用)。
Host: blog.csdn.net
//第三行中包含的是首部Connection,keep-alive不關閉連接配接特性(用戶端和伺服器之間用于傳輸HTTP資料的TCP連接配接不會關閉,如果用戶端再次通路這個伺服器上的網頁,會繼續使用這一條已經建立的連接配接),Keep-Alive不會永久保持連接配接,它有一個保持時間.參閱:https://en.wikipedia.org/wiki/HTTP_persistent_connection
Connection: keep-alive
//用于指定緩存指令,緩存指令是單向的(響應中出現的緩存指令在請求中未必會出現),且是獨立的(一個消息的緩存指令不會影響另一個消息處理的緩存機制),HTTP1.0使用的類似的報頭域為Pragma。
請求時的緩存指令包括:no-cache(用于訓示請求或響應消息不能緩存)、no-store、max-age、max-stale、min-fresh、only-if-cached;
響應時的緩存指令包括:public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage.
eg:為了訓示IE浏覽器(用戶端)不要緩存頁面.
Cache-Control: max-age=0
//Accept請求報頭域用于指定用戶端接受哪些類型的資訊。eg:Accept:image/gif,表明用戶端希望接受GIF圖象格式的資源;Accept:text/html,表明用戶端希望接受html文本。
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
起始行(start line)
請求封包的起始行,或稱為請求行。包含了一個方法和一個請求的URL。這個方法描述了伺服器應該執行的操作,請求URL描述了要對哪個資源執行這個方法。請求行中還包含HTTP的版本,用來告知伺服器,用戶端使用的是哪種HTTP版本。
HTTP協定常用方法
方法 | 描述 | 是否包含主體 |
---|---|---|
GET | 從伺服器擷取一份文檔 | 否 |
HEAD | 隻從伺服器擷取文檔的首部 | 否 |
POST | 向伺服器發送需要處理的資料 | 是 |
PUT | 将請求的主題部分存儲在伺服器上 | 是 |
TRACE | 對可能經過代理伺服器傳送到伺服器上去的封包進行追蹤 | 否 |
OPTIONS | 決定可以在伺服器執行哪些方法 | 否 |
DELETE | 從伺服器上删除一份文檔 | 否 |
HTTP協定響應狀态碼
整體範圍 | 已定義範圍 | 分類 |
---|---|---|
100 ~ 199 | 100 ~ 101 | 資訊提示 |
200 ~ 299 | 200 ~ 206 | 成功 |
300 ~ 399 | 300 ~ 305 | 重定向 |
400 ~ 499 | 400 ~ 415 | 用戶端錯誤 |
500 ~ 599 | 500 ~ 505 | 伺服器錯誤 |
詳細狀态:
狀态碼 | 原因短語 | 含義 |
---|---|---|
100 | Continue | 說明收到了請求的初識部分,請用戶端繼續。發送了這個狀态碼之後,伺服器在收到請求之後必須進行響應。 |
101 | Switching Protocols | 說明伺服器正在根據用戶端的指定,将協定切換成Update 首部所列協定 |
= | ===== | ============================== |
200 | OK | 請求成功,實體的主體部分包含了所請求的資源 |
201 | Created | 用于建立伺服器對象的請求(如:PUT)。響應的屍體主體部分中應該包含各種引用了已建立的資源的URL,Location首部包含的則是具體的引用。 |
202 | Accepted | 請求已被接受,但伺服器還未對其執行任何動作。不能保證伺服器會完成這個請求,這隻是意味着接受請求時,它看起來是有效的 |
203 | Non-Authoritative Informaion | 實體首部包含的資訊不是來自于源端伺服器,而是來自資源的一份副本。如果中間節點上有一份資源副本,但無法或者沒有對它所發送的與資源有關的元資訊進行驗證,就會出現這種情況。 |
204 | No Content | 響應封包中包含若幹首部和一個狀态行,但沒有實體的主體部分 |
205 | Reset Content | 另一個主要用于浏覽器的代碼。負責告知浏覽器清除目前頁面中的所有HTML表單元素 |
206 | Partial Content | 成功執行了一個部分或Range請求 |
= | ===== | ============================== |
300 | Multiple Choices | 用戶端請求一個實際指向多個資源的URL時傳回,比如伺服器上有某個HTML文檔的英文或文法版本。 |
301 | Moved Permanently | 永久重定向,告訴用戶端以後應從新位址通路. |
302 | Found | 與301狀态碼類似,但是,用戶端應該使用Location首部給出的URL來臨時定位資源。 |
303 | See Other | 對于POST請求,它表示請求已經被處理,用戶端可以接着使用GET方法去請求Location裡的URI。如在檔案上傳完成後讓用戶端自動重定向到一個上傳成功的結果頁面。 |
304 | Not Modified | 用戶端可以通過所包含的請求首部,使其請求變成有條件的。自從上次請求後,請求的網頁未修改過。伺服器傳回此響應時,不會傳回網頁内容。如果網頁自請求者上次請求後再也沒有更改過,您應将伺服器配置為傳回此響應(稱為 If-Modified-Since HTTP 标頭)。伺服器可以告訴 Googlebot 自從上次抓取後網頁沒有變更,進而節省帶寬和開銷。 |
305 | Use Proxy | 請求者隻能使用代理通路請求的網頁。如果伺服器傳回此響應,表示請求者應使用代理。 |
307 | Temporary Redirect | 伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來響應以後的請求。此代碼與響應 GET 和 HEAD 請求的301代碼類似,會自動将請求者轉到不同的位置,但您不應使用此代碼來告訴 Googlebot 某個頁面或網站已經移動,因為 Googlebot 會繼續抓取原有位置并編制索引。 |
= | ===== | ============================== |
400 | Bad Request | 用于告知用戶端它發送了一個錯誤的請求,伺服器不了解請求的文法。 |
401 | Unauthorized | 請求要求身份驗證。對于登入後請求的網頁,伺服器可能傳回此響應。 |
402 | Payment Required | 未使用 |
403 | Forbidden | 伺服器拒絕請求。 |
404 | Not Found | 伺服器無法找到所請求的URL,例如,對于伺服器上不存在的網頁經常會傳回此代碼。 |
405 | Method Not Allowed | 禁用請求中指定的方法 |
406 | Not Acceptable | 無法使用請求的内容特性響應請求的網頁。 |
407 | Proxy Authentication Required | 此狀态碼與 401(未授權)類似,但指定請求者應當授權使用代理。如果伺服器傳回此響應,還表示請求者應當使用代理。 |
408 | Request Timeout | 伺服器等候請求時發生逾時。 |
409 | Conflict | 伺服器在完成請求時發生沖突。伺服器必須在響應中包含有關沖突的資訊。伺服器在響應與前一個請求相沖突的 PUT 請求時可能會傳回此代碼,以及兩個請求的差異清單。 |
410 | Gone | 如果請求的資源已永久删除,伺服器就會傳回此響應。該代碼與 404(未找到)代碼類似,但在資源以前存在而現在不存在的情況下,有時會用來替代 404 代碼。如果資源已永久移動,您應使用 301 指定資源的新位置。 |
411 | Length Required | 伺服器不接受不含有效内容長度标頭字段的請求。 |
412 | Precondition Failed | 伺服器未滿足請求者在請求中設定的其中一個前提條件。 |
413 | Request Entity Too Large | 伺服器無法處理請求,因為請求實體過大,超出伺服器的處理能力。 |
414 | Request URI Too Long | 請求的 URI(通常為網址)過長,伺服器無法處理。 |
415 | Unsupported Media Type | 請求的格式不受請求頁面的支援。 |
416 | Requested Range Not Satisfiable | 如果頁面無法提供請求的範圍,則伺服器會傳回此狀态碼。 |
417 | Expectation Failed | 請求的Expect 請求首部包含了一個期望,但伺服器無法滿足此期望時傳回此狀态碼。 |
= | ===== | ============================== |
500 | Internal Server Error | 伺服器遇到錯誤,無法完成請求。 |
501 | Not Implemented | 伺服器不具備完成請求的功能。例如,伺服器無法識别請求方法時可能會傳回此代碼。 |
502 | Bad Gateway | 伺服器作為網關或代理,從上遊伺服器收到無效響應。 |
503 | Service Unavailable | 伺服器目前無法使用(由于超載或停機維護)。通常,這隻是暫時狀态。 |
504 | Gateway Timeout | 伺服器作為網關或代理,但是沒有及時從上遊伺服器收到請求。 |
505 | HTTP Version Not Supported | 伺服器不支援請求中所用的 HTTP 協定版本。 |
首部(header)
通用首部
既可以出現在請求封包中,也可以出現在響應封包中。
首部 | 描述 |
---|---|
Connection | 允許用戶端和伺服器指定與請求/響應連接配接有關的選項 |
Date | 提供日期和時間标志,說明封包時什麼時間建立的 |
MIME-Version | 給出了發送端使用的MIME版本 |
Trailer | 如果封包采用了分塊傳輸編碼(chunked transfer encoding)方式,就可以用這個首部列出位于封包拖鞋 (trailer)部分的首部集合。 |
Transfer-Encoding | 告知接收端為了保證封包的可靠傳輸,對封包采用了什麼編碼方式。 |
Update | 給出了發送端可能想要”更新”使用的新版本或協定 |
Via | 顯示了封包經過的中間節點(代理、網關) |
通用緩存首部:
首部 | 描述 |
---|---|
Cache-Control | 用于随封包傳送緩存訓示 |
Pragma | 另一種随封包傳送訓示的方式,但并不專用于緩存 |
請求首部
請求首部是在請求封包中有意義的首部。用于說明是誰或什麼在發送請求,請求源自何處,或者用戶端的喜好及能力。伺服器可以根據請求首部給出的用戶端的資訊,試着為用戶端提供更好的響應
請求報頭舉例:
GET /liuxinmingcode HTTP/1.1(CRLF)
Host: blog.csdn.net(CRLF)
Connection: keep-alive(CRLF)
Cache-Control: max-age=0(CRLF)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8(CRLF)
Upgrade-Insecure-Requests: 1(CRLF)
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36(CRLF)
Accept-Encoding: gzip, deflate, sdch(CRLF)
Accept-Language: zh-CN,zh;q=0.8(CRLF)
(CRLF)
首部 | 描述 |
---|---|
Client-IP | 提供了運作用戶端的機器的IP位址 |
From | 提供了用戶端使用者的E-mail位址 |
Host | 給出了接收請求的伺服器的主機名和端口号 |
Referer | 提供了包含目前請求URI的文檔的URL |
UA-Color | 提供了與用戶端顯示器的顯示顔色有關的資訊 |
UA-CPU | 給出了用戶端CPU的類型或制造商 |
US-Disp | 提供了與用戶端顯示器(螢幕)能力有關的資訊 |
US-OS | 給出了用戶端顯示器的像素資訊 |
UA-Pixels | 提供了用戶端顯示器的像素資訊 |
User-Agent | 将發起請求的應用程式名稱告知伺服器(User-Agent)使用者代理,其實不就是浏覽器嗎 |
Accept首部
Accept首部為用戶端提供了一種将其喜好和能力告知伺服器的方式,包括他們想要什麼,可以使用什麼,以及最重要的,他們不想要什麼。這樣伺服器就可以根據這些額外資訊,對要發送的内容做出更明智的決定。Accept首部會使連接配接的兩端都受益。用戶端會得到他們想要的内容,伺服器則不會浪費其時間和帶寬來發送用戶端無法使用的東西。
首部 | 描述 |
---|---|
Accept | 告訴伺服器能夠發送哪些媒體類型 |
Accept-Charset | 告訴伺服器能夠發送哪些字元集 |
Accept-Encoding | 告訴伺服器能夠發送哪些編碼方式 |
Accept-Language | 告訴伺服器能夠發送哪些語言 |
TE | 告訴伺服器可以使用哪些擴充傳輸編碼 |
條件請求首部
有時用戶端希望為請求加上某些限制。比如用戶端已經有了一份副本,就希望隻在伺服器上的文檔與用戶端擁有的副本有所差別時,才請求伺服器傳輸文檔。通過條件請求首部,用戶端就可以加上這種限制,要求伺服器在對請求進行相應之前,確定某個請求為真。
首部 | 描述 |
---|---|
Expect | 允許用戶端列出某請求所要求的伺服器行為 |
If-Match | 如果實體标記與文檔目前的實體标記相比對,就或者這份文檔 |
If-Modified-Since | 除非在某個指定的日期之後資源被修改過,否則就限制這個請求 |
If-Range | 允許對文檔的某個範圍進行條件請求 |
If-Unmodified-Since | 除非在某個指定的日期之後資源沒有被修改過,否則就限制這個請求 |
Range | 如果伺服器支援範圍請求,就請求資源的指定範圍 |
安全請求首部
代理請求首部
響應首部
響應封包由自己的響應首部集。響應首部為用戶端提供了一些額外的資訊,比如誰在發送響應、響應者的功能,甚至與響應相關的一些特殊指令。這些首部有助于用戶端處理響應,并在将來發起更好的請求。
響應報頭舉例:
HTTP/1.1 OK
Server: openresty
Date: Sun, 20 Dec 2015 07:38:40 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Keep-Alive: timeout=20
Vary: Accept-Encoding
Cache-Control: private
X-Powered-By: PHP 5.4.28
Content-Encoding: gzip
協商首部
安全響應首部
實體首部
請求和響應消息都可以傳送一個實體。一個實體由實體報頭域和實體正文組成,但并不是說實體報頭域和實體正文要在一起發送,可以隻發送實體報頭域。實體報頭定義了關于實體正文(eg:有無實體正文)和請求所辨別的資源的元資訊。
内容首部
首部 | 描述 |
---|---|
Content-Base | 解析主體中的相對URL時使用的基礎URL |
Content-Encoding | 實體報頭域被用作媒體類型的修飾符,它的值訓示了已經被應用到實體正文的附加内容的編碼,因而要獲得Content-Type報頭域中所引用的媒體類型,必須采用相應的解碼機制。Content-Encoding這樣用于記錄文檔的壓縮方法,eg:Content-Encoding:gzip |
Content-Language | 實體報頭域描述了資源所用的自然語言。沒有設定該域則認為實體内容将提供給所有的語言閱讀者。eg:Content-Language:da |
Content-Length | 實體報頭域用于指明實體正文的長度,以位元組方式存儲的十進制數字來表示。 |
Content-Type | 實體報頭域用語指明發送給接收者的實體正文的媒體類型。eg:Content-Type:text/html;charset=ISO-8859-1 Content-Type:text/html;charset=GB2312 |
實體緩存首部
首部 | 描述 |
---|---|
Expires | 實體報頭域給出響應過期的日期和時間。為了讓代理伺服器或浏覽器在一段時間以後更新緩存中(再次通路曾通路過的頁面時,直接從緩存中加載,縮短響應時間和降低伺服器負載)的頁面,我們可以使用Expires實體報頭域指定頁面過期的時間。eg:Expires:Thu,15 Sep 2006 16:23:12 GMT HTTP1.1的用戶端和緩存必須将其他非法的日期格式(包括0)看作已經過期。eg:為了讓浏覽器不要緩存頁面,我們也可以利用Expires實體報頭域,設定為0,jsp中程式如下:response.setDateHeader(“Expires”,”0”); |
Last-Modified | 實體報頭域用于訓示資源的最後修改日期和時間。 |