HTTP協議(Hyper Text Transfer Protocol,超文本傳輸協議)是一個簡單的請求-響應協議,它通常運行在TCP之上。是因特網上應用最為廣泛的一種網絡傳輸協議,所有的WWW文件都必須遵守此標準。HTTP它指定了客戶端可能發送給服務器什么樣的消息以及得到什么樣的響應。請求和響應消息的頭以ASCII碼形式給出;而消息內容則具有一個類似MIME的格式。基于TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。
HTTP是基于客戶/服務器模式,且面向連接的。主要有以下四步:
(1)客戶與服務器建立連接;
(2)客戶向服務器提出請求;
(3)服務器接受請求,并根據請求返回相應的文件作為應答;
(4)客戶與服務器關閉連接。
特別說明:
HTTP是無連接:無連接的含義是限制每次連接只處理一個請求。客戶與服務器之間的HTTP連接是一種一次性連接,它限制每次連接只處理一個請求,當服務器返回本次請求的應答后便立即關閉連接,下次請求再重新建立連接。這種一次性連接主要考慮到WWW服務器面向的是Internet中成千上萬個用戶,且只能提供有限個連接,故服務器不會讓一個連接處于等待狀態,及時地釋放連接可以大大提高服務器的執行效率,可以節省傳輸時間。
HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對于事務處理沒有記憶能力。即服務器不保留與客戶交易時的任何狀態。這就大大減輕了服務器記憶負擔,從而保持較快的響應速度。但是缺少狀態意味著如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
HTTP是媒體獨立的:這意味著,只要客戶端和服務器知道如何處理的數據內容,任何類型的數據都可以通過HTTP發送。客戶端以及服務器指定使用適合的MIME-type內容類型。
HTTP請求方法主要有九種。此外還有LINK和UNLINK,不過已被HTTP/1.1廢棄。
HTTP0.9這是HTTP最早大規模使用的版,現已過時。只有GET一種請求方法。
HTTP1.0 支持了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1 新增了五種請求方法:OPTIONS、PUT、DELETE、TRACE 和 CONNECT 方法。
在HTTP/1.1標準制定之后,又陸續擴展了一些方法。其中使用中較多的是 PATCH方法
在此處我們要引入兩個概念,即等冪性和安全性,之前向大家介紹過這兩個概念,這里只是大致提一下。(詳見學習筆記-RESTful基本規范)
等冪性:簡單點說就是一次請求和多次請求,資源的狀態是一樣。
安全性:對該接口訪問,不會使服務器端資源的狀態發生改變。
GET:GET請求會顯示請求指定的資源。一般來說GET方法應該只用于數據的讀取,而不應當用于會產生副作用的非等冪的操作中。GET會方法請求指定的頁面信息,并返回響應主體,GET被認為是不安全的方法,因為GET方法會被網絡蜘蛛等任意的訪問。
HEAD:HEAD方法與GET方法一樣,都是向服務器發出指定資源的請求。但是,服務器在響應HEAD請求時不會回傳資源的內容部分,即:響應主體。這樣,我們不傳輸全部內容的情況下,就可以獲取服務器的響應頭信息。HEAD方法常被用于客戶端查看服務器的性能。
POST:POST請求會 向指定資源提交數據,請求服務器進行處理,如:表單數據提交、文件上傳等,請求數據會被包含在請求體中。POST方法是非等冪的方法,因為這個請求可能會創建新的資源或/和修改現有資源。
PUT:PUT請求會身向指定資源位置上傳其最新內容,PUT方法是等冪的方法。通過該方法客戶端可以將指定資源的最新數據傳送給服務器取代指定的資源的內容。
DELETE:DELETE請求用于請求服務器刪除所請求URI所標識的資源。DELETE請求后指定資源會被刪除,DELETE方法也是等冪的。
CONNECT:CONNECT方法是HTTP/1.1協議預留的,能夠將連接改為管道方式的代理服務器。通常用于SSL加密服務器的鏈接與非加密的HTTP代理服務器的通信。
OPTIONS:OPTIONS請求與HEAD類似,一般也是用于客戶端查看服務器的性能。 這個方法會請求服務器返回該資源所支持的所有HTTP請求方法,該方法會用'*'來代替資源名稱,向服務器發送OPTIONS請求,可以測試服務器功能是否正常。
TRACE:TRACE請求服務器回顯其收到的請求信息,該方法主要用于HTTP請求的測試或診斷。
PATCH:PATCH與PUT請求類似,同樣用于資源的更新。不同的是PATCH一般用于資源的部分更新,而PUT一般用于資源的整體更新。當資源不存在時,PATCH會創建一個新的資源,而PUT只會對已在資源進行更新。
特別說明:
(1)方法名稱是區分大小寫的,當某個請求所針對的資源不支持對應的請求方法的時候,服務器應當返回狀態碼405;當服務器不認識或者不支持對應的請求方法時,應返回狀態碼501。
(2)HTTP服務器至少應該實現GET和HEAD/POST方法,其他方法都是可選的,此外除上述方法,特定的HTTP服務器支持擴展自定義的方法。
請求頭用于說明是誰或什么在發送請求、請求源于何處,或者客戶端的喜好及能力。服務器可以根據請求頭部給出的客戶端信息,試著為客戶端提供更好的響應。請求頭域可能包含下列字段Accept、Accept-Charset、Accept- Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since、If-Match、If-None-Match、If-Range、If-Unmodified-Since、Proxy-Authorization、Range、Referer、User-Agent等。對請求頭域的擴展要求通訊雙方都支持,如果存在不支持的請求頭域,一般將會作為實體頭域處理。
Accept,瀏覽器端能夠處理的內容類型。例如: Accept: text/html 代表瀏覽器可以接受服務器回發的類型為 text/html 也就是我們常說的html文檔。如果服務器無法返回text/html類型的數據,服務器應該返回一個406錯誤(non acceptable)。通配符 * 代表任意類型,例如 Accept: */* 代表瀏覽器可以處理所有類型,(一般瀏覽器發給服務器都是發這個)。
Accept_Charset,瀏覽器能夠顯示的字符集。
Accept-Encoding:瀏覽器能夠進行解碼的數據編碼方式,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法,比如gzip。Servlet能夠向支持gzip的瀏覽器返回經gzip編碼的HTML頁面。許多情形下這可以減少5到10倍的下載時間。
Accept-Language, 瀏覽器當前設置的語言。 瀏覽器所希望的語言種類,當服務器能夠提供一種以上的語言版本時要用到。
Authorization,授權信息,通常出現在對服務器發送的WWW-Authenticate頭的應答中。
From,請求發送者的email地址,由一些特殊的Web客戶程序使用,瀏覽器不會用到它。
Host,發送請求的頁面的域名。(發送請求時,該報頭域是必需的),請求報頭域主要用于指定被請求資源的Internet主機和端口號,它通常從HTTP URL中提取出來的。
If-Modified-Since,瀏覽器緩存時間記錄。 把瀏覽器端緩存頁面的最后修改時間發送到服務器去,服務器會把這個時間與服務器上實際文件的最后修改時間進行對比。
If-Match,如果對象的 ETag 沒有改變,其實也就意味著對象沒有改變,才執行請求的動作,獲取文檔。
If-None-Match, If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 當用戶再次請求該資源時,將在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服務器驗證資源的ETag沒有改變(該資源沒有更新),將返回一個304狀態告訴客戶端使用本地緩存文件。否則將返回200狀態和新的資源和Etag. 使用這樣的機制將提高網站的性能。
If-Range,瀏覽器告訴 WEB 服務器,如果我請求的對象沒有改變,就把我缺少的部分給我,如果對象改變了,就把整個對象給我。瀏覽器通過發送請求對象的ETag 或者自己所知道的最后修改時間給 WEB 服務器,讓其判斷對象是否改變了。總是跟 Range 頭部一起使用。
If-Unmodified-Since,如果請求的對象在該頭部指定的時間之后沒修改過,才執行請求的動作(比如返回對象)。
Proxy-Authorization,瀏覽器響應代理服務器的身份驗證請求,提供自己的身份信息。
Range,瀏覽器(比如 Flashget 多線程下載時)告訴 WEB 服務器自己想取對象的哪部分。例如:Range: bytes=1173546
Referer,發送請求的頁面的URI。當瀏覽器向web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器借此可以獲得一些信息用于處理。
User-Agent,瀏覽器的用戶代理字符串。告訴HTTP服務器, 客戶端使用的和瀏覽器的名稱和版本。
If-Modified-Since,只有當所請求的內容在指定的日期之后又經過修改才返回它,否則返回304"Not Modified"應答。
Connection,瀏覽器與服務器的連接類型,表示是否需要持久連接。Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。 Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉。當客戶端再次發送Request,需要重新建立TCP連接。
Cookie,用來存儲一些用戶信息以便讓服務器辨別用戶身份的(大多數需要登錄的網站上面會比較常見),這是最重要的請求頭信息之一。如Cookie會存儲一些用戶的用戶名和密碼,當用戶登錄后就會在客戶端產生一個Cookie來存儲相關信息,這樣瀏覽器通過讀取Cookie的信息去服務器上驗證并通過后會判定你是合法用戶,從而允許查看相應網頁。當然Cookie里面的數據不僅僅是上述范圍,還有很多信息可以存儲是Cookie里面,比如sessionid等。
Cache-Control,指明當前資源的有效期,控制瀏覽器是否直接從瀏覽器緩存取數據,還是重新發請求到服務器獲取數據。網頁的緩存控制是由HTTP中的"Cache-control"來實現的,常見值有private、no-cache、max-age、must-revalidate等,默認為private。
Content-Length:表示請求消息正文的長度。
Pragma,指定"no-cache"值表示服務器必須返回一個刷新后的文檔,即使它是而且已經有了頁面的本地拷貝。
UA-Pixels,UA-Color,UA-OS,UA-CPU,由某些版本的IE瀏覽器所發送的非標準的請求頭,表示屏幕大小、顏色深度、操作系統和CPU類型。
響應頭向客戶端提供一些額外信息,比如誰在發送響應、響應者的功能,甚至與響應相關的一些特殊指令。這些頭部有助于客戶端處理響應,并在將來發起更好的請求。響應頭域包含Age、Location、Public、Server、Vary、WWW-Authenticate等。對響應頭域的擴展要求通訊雙方都支持,如果存在不支持的響應頭域,一般將會作為實體頭域處理。
Age,當代理服務器用自己緩存的實體去響應請求時,用該頭部表明該實體從產生到現在經過多長時間了。
Location,表示客戶應當到哪里去提取文檔。Location通常不是直接設置的,而是通過HTTPServletResponse的sendRedirect方法,該方法同時設置狀態代碼為302。
Public:指示響應可被任何緩存區緩存,可以用緩存內容回應任何用戶。
Server,服務器名字。Servlet一般不設置這個值,而是由Web服務器自己設置。WEB 服務器表明自己是什么軟件及版本等信息。例如:Server:Apache/2.0.61 (Unix)
Vary,WEB服務器用該頭部的內容告訴 Cache 服務器,在什么條件下才能用本響應所返回的對象響應后續的請求。假如源WEB服務器在接到第一個請求消息時,其響應消息的頭部為:Content-Encoding: gzip; Vary: Content-Encoding,那么Cache服務器會分析后續請求消息的頭部,檢查其Accept-Encoding,是否跟先前響應的Vary頭部值一致,即是否使用相同的內容編碼方法,這樣就可以防止Cache服務器用自己Cache 里面壓縮后的實體響應給不具備解壓能力的瀏覽器。例如:Vary:Accept-Encoding。
WWW-Authenticate,客戶應該在Authorization中提供什么類型的授權信息。在包含401(Unauthorized)狀態行的應答中這個頭是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。Servlet一般不進行這方面的處理,而是讓Web服務器的專門機制來控制受密碼保護頁面的訪問
Accept-Ranges,WEB服務器表明自己是否接受獲取其某個實體的一部分(比如文件的一部分)的請求。bytes:表示接受,none:表示不接受。
Allow,服務器支持哪些請求方法(如GET、POST等)。
Content-Encoding,文檔的編碼(Encode)方法。只有在解碼之后才可以得到Content-Type頭指定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。
Content-Length,表示內容長度。只有當瀏覽器使用持久HTTP連接時才需要這個數據。如果你想要利用持久連接的優勢,可以把輸出文檔寫入 ByteArrayOutputStream,完成后查看其大小,然后把該值放入Content-Length頭,最后通過byteArrayStream.writeTo(response.getOutputStream()發送內容。
Content-Type,表示后面的文檔屬于什么MIME類型。Servlet默認為text/plain,但通常需要顯式地指定為text/html。由于經常要設置Content-Type,因此HTTPServletResponse提供了一個專用的方法setContentType。
Date,當前的GMT時間。你可以用setDateHeader來設置這個頭以避免轉換時間格式的麻煩。
Expires,過期時間。應該在什么時候認為文檔已經過期,從而不再緩存它?
Last-Modified,文檔的最后改動時間。客戶可以通過If-Modified-Since請求頭提供一個日期,該請求將被視為一個條件GET,只有改動時間遲于指定時間的文檔才會返回,否則返回一個304(Not Modified)狀態。Last-Modified也可用setDateHeader方法來設置。
Refresh,表示瀏覽器應該在多少時間之后刷新文檔。
Set-Cookie,設置和頁面關聯的Cookie。Servlet不應使用response.setHeader("Set-Cookie", ...),而是應使用HTTPServletResponse提供的專用方法addCookie。參見下文有關Cookie設置的討論。
HTTP狀態碼用來告訴客戶端發生了什么事情。狀態碼是在每條響應報文的起始行返回的,會返回一個數字狀態和一個可讀的狀態。數字碼便于程序進行差錯處理,原因短語便于人們理解
200到299之間的狀態碼表示成功,300到399之間的代碼表示資源已經被轉移走啦,400到499之間的代碼表示客戶端請求出錯了,500到599之間的代碼表示服務器出錯了
此處只是HTTP的相關狀態碼。RESTful有一套自己的標準,詳見學習筆記-RESTful基本規范。
1XX:信息狀態碼
100===>繼續===>初始的請求已經接受,請客戶端繼續發送剩余部分
101===>切換協議===>請求者要求服務器切換協議,服務器已確定切換
2XX:成功狀態碼
200===>成功===>服務器已成功處理了請求
201===>已創建===>請求成功并且服務器創建了新的資源
202===>已接受===>服務器已接受請求,但尚未處理
203===>非授權信息===>服務器已成功處理請求,但返回的信息可能來自另一個來源
204===>無內容===>服務器已成功處理請求,但返回的資源可能來自另一個來源
205===>重置內容===>服務器處理成功,用戶終端重置文檔視圖
206===>部分內容===>服務器成功處理了部分GET請求
3XX:重定向狀態碼
300===>多種選擇===>針對請求,服務器可執行多種操作
301===>永久移動===>請求的頁面已永久跳轉到新的url
302===>臨時移動===>服務器目前從不同位置的網頁響應請求,但請求仍繼續使用原有位置來進行以后的請求
303===>查看其他位置===>請求者應當對不同的位置使用單獨的GET請求來檢索響應時,服務器返回此代碼
304===>未修改===>自從上次請求后,請求的網頁未修改過
305===>使用代理===>請求者只能使用代理訪問請求的網頁
307===>臨時重定向===>服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求
4XX:客戶端錯誤狀態碼
400===>錯誤請求===>服務器不理解請求的語法
401===>未授權===>請求要求用戶的身份驗證
403===>禁止===>服務器拒絕請求
404===>未找到===>服務器找不到請求的頁面
405===>方法禁用===>禁用請求中指定的方法
406===>不接受===>無法使用請求的內容特性響應請求的頁面
407===>需要代理授權===>請求需要代理的身份認證
408===>請求超時===>服務器等候請求時發生超時
409===>沖突===>服務器在完成請求時發生沖突
410===>已刪除===>客戶端請求的資源已經不存在
411===>需要有效長度===>服務器不接受不含有效長度表頭字段的請求
412===>未滿足前提條件===>服務器未滿足請求者在請求中設置的其中一個前提條件
413===>請求實體過大===>由于請求實體過大,服務器無法處理,因此拒絕請求
414===>請求url過長===>請求的url過長,服務器無法處理
415===>不支持格式===>服務器無法處理請求中附帶媒體格式
416===>范圍無效===>客戶端請求的范圍無效
417===>未滿足期望===>服務器無法滿足請求表頭字段要求
5XX:服務端錯誤狀態碼
500===>服務器錯誤===>服務器內部錯誤,無法完成請求
501===>尚未實施===>服務器不具備完成請求的功能
502===>錯誤網關===>服務器作為網關或代理出現錯誤
503===>服務不可用===>服務器目前無法使用
504===>網關超時===>網關或代理服務器,未及時獲取請求
505===>不支持版本===>服務器不支持請求中使用的HTTP協議版本
本文的初衷為學習筆記的分享,部分圖文來源于網絡,如侵,聯刪。
. HTTP請求格式
做過Socket編程的人都知道,當我們設計一個通信協議時,“消息頭/消息體”的分割方式是很常用的,消息頭告訴對方這個消息是干什么的,消息體告訴對 方怎么干。HTTP協議傳輸的消息也是這樣規定的,每一個HTTP包都分為HTTP頭和HTTP體兩部分,消息體是可選的,而消息頭是必須的。每當我們打 開一個網頁,在上面點擊右鍵,選擇“查看源文件”,這時看到的HTML代碼就是HTTP的消息體,那么消息頭可以通過瀏覽器的開發工具或者插件可以看到, 如果火狐的Firebug,IE的Httpwatch。
客戶端通過發送 HTTP 請求向服務器請求對資源的訪問。 它向服務器傳遞了一個數據塊,也就是請求信息,HTTP 請求由三部分組成:請求行、 請求頭和請求正文。
請求行:請求方法 URI 協議/版本
請求頭(Request Header)
請求正文
下面是一個HTTP請求的數據:
POST /index.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Content-Length:25
Content-Type:application/x-www-form-urlencoded
username=aa&password=1234
1、請求行:請求方法URI協議/版本
請求的第一行是“方法 URL 協議/版本”,并以 回車換行作為結尾。請求行以空格分隔。格式如下:
POST /index.php HTTP/1.1
以上代碼中“GET”代表請求方法,“//ndex.php”表示URI,“HTTP/1.1代表協議和協議的版本。
根據HTTP標準,HTTP請求可以使用多種請求方法。例如:HTTP1.1支持7種請求方法:GET、POST、HEAD、OPTIONS、PUT、DELETE和TARCE。在Internet應用中,最常用的方法是GET和POST。
URL完整地指定了要訪問的網絡資源,通常只要給出相對于服務器的根目錄的相對目錄即可,因此總是以“/”開頭,最后,協議版本聲明了通信過程中使用HTTP的版本。
請求方法
在 HTTP 協議中,HTTP 請求可以使用多種請求方法,這些方法指明了要以何種方式來訪問 Request-URI 所標識的資源。HTTP1.1 支持的請求方法如下表所示:
HTTP1.1 中的請求方式:
方法
作用
GET
請求獲取由 Request-URI 所標識的資源
POST
請求服務器接收在請求中封裝的實體,并將其作為由 Request-Line 中的 Request-URI 所標識的資源的一部分
HEAD
請求獲取由 Request-URI 所標識的資源的響應消息報頭
PUT
請求服務器存儲一個資源,并用 Request-URI 作為其標識符
DELETE
請求服務器刪除由 Request-URI 所標識的資源
TRACE
請求服務器回送到的請求信息,主要用于測試或診斷
CONNECT
保留將來使用
OPTIONS
請求查詢服務器的性能,或者查詢與資源相關的選項和需求
重點介紹 GET、POST 和 HEAD 三個方法:
(1)GET
GET 方法用于獲取由 Request-URI 所標識的資源的信息,常見的形式是:
GET Request-URI HTTP/1.1
GET方法是默認的HTTP請求方法,例如當我們通過在瀏覽器的地址欄中直接輸入網址的方式去訪問網頁的時候,瀏覽器采用的就是 GET 方法向服務器獲取資源。
我們可以使用GET方法來提交表單數據,用GET方法提交的表單數據只經過了簡單的編碼,同時它將作為URL的一部分向服務器發送,因此,如果使用GET方法來提交表單數據就存在著安全隱患上。例如:
Http://localhost/login.php?username=aa&password=1234
從上面的URL請求中,很容易就可以辯認出表單提交的內容。(?之后的內容)另外由于GET方法提交的數據是作為URL請求的一部分所以提交的數據量不能太大。這是因為瀏覽器對url的長度有限制
各種瀏覽器也會對url的長度有所限制,下面是幾種常見瀏覽器的url長度限制:(單位:字符)
IE : 2803
Firefox:65536
Chrome:8182
Safari:80000
Opera:190000
(2)POST
POST方法是GET方法的一個替代方法,它主要是向Web服務器提交表單數據,尤其是大批量的數據。 在請求頭信息結束之后的兩個回車換行之后(實際是空一行),就是表單提交的數據。如上面提到的post表單數據:
username=aa&password=1234
POST方法克服了GET方法的一些缺點。通過POST方法提交表單數據時,數據不是作為URL請求的一部分而是作為標準數據傳送給Web服務器,這就克 服了GET方法中的信息無法保密和數據量太小的缺點。因此,出于安全的考慮以及對用戶隱私的尊重,通常表單提交時采用POST方法。
從編程的角度來講,如果用戶通過GET方法提交數據,則數據存放在QUERY_STRING環境變量中,而POST方法提交的數據則可以從標準輸入流中獲取。
GET與POST方法有以下區別:
1、 在客戶端,Get方式在通過URL提交數據,數據在URL中可以看到;POST方式,數據放在HTTP包的body中。
2、 GET方式提交的數據大小有限制(因為瀏覽器對URL的長度有限制),而POST則沒有此限制。
3、安全性問題。正如在(1)中提到,使用 Get 的時候,參數會顯示在地址欄上,而 Post 不會。所以,如果這些數據是中文數據而且是非敏感數據,那么使用 get;如果用戶輸入的數據不是中文字符而且包含敏感數據,那么還是使用 post為好。
4.、服務器取值方式不一樣。GET方式取值,如php可以使用$_GET來取得變量的值,而POST方式通過$_POST來獲取變量的值。
(3)HEAD
HEAD 方法與 GET 方法幾乎是相同的,它們的區別在于 HEAD 方法只是請求消息報頭,而不是完整的內容。對于 HEAD 請求的回應部分來說,它的 HTTP 頭部中包含的信息與通過 GET 請求所得到的信息是相同的。利用這個方法,不必傳輸整個資源內容,就可以得到 Request-URI 所標識的資源的信息。這個方法通常被用于測試超鏈接的有效性,是否可以訪問,以及最近是否更新。
要注意的是,在 HTML 文檔中,書寫 get 和 post,大小寫都可以,但在 HTTP 協議中的 GET 和 POST 只能是大寫形式。
2. 請求頭
每個頭域由一個域名,冒號(:)和域值三部分組成。域名是大小寫無關的,域值前可以添加任何數量的空格符,頭域可以被擴展為多行,在每行開始處,使用至少一個空格或制表符。
HTTP最常見的請求頭如下:
Transport 頭域
Connection:
作用:表示是否需要持久連接。
如果服務器看到這里的值為“Keep-Alive”,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久連接),它就可以利用持久連接的優點,當頁面包含多個元素時(例如Applet,圖片),顯著地減少下載所需要的時間。要實現這一點,服務器需要在應答中發送一個Content-Length頭,最簡單的實現方法是:先把內容寫入 ByteArrayOutputStream,然后在正式寫出內容之前計算它的大小;
例如: Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的 網頁,會繼續使用這一條已經建立的連接
例如: Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉, 當客戶端再次發送Request,需要重新建立TCP連接。
Host(發送請求時,該報頭域是必需的)
Host請求報頭域主要用于指定被請求資源的Internet主機和端口號,它通常從HTTP URL中提取出來的。
eg:http://;localhost/index.html
瀏覽器發送的請求消息中,就會包含Host請求報頭域,如下:
Host:localhost
此處使用缺省端口號80,若指定了端口號8080,則變成:Host:localhost:8080
Client 頭域
Accept:
作用:瀏覽器可以接受的媒體類型(MIME類型),
例如: Accept: text/html 代表瀏覽器可以接受服務器回發的類型為 text/html 也就是我們常說的html文檔, 如果服務器無法返回text/html類型的數據,服務器應該返回一個406錯誤(non acceptable)。
通配符 * 代表任意類型。例如 Accept: */* 代表瀏覽器可以處理所有類型,(一般瀏覽器發給服務器都是發這個)
Accept-Encoding:
作用: 瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支持壓縮,支持什么壓縮方法(gzip,deflate),(注意:這不是只字符編碼);
例如: Accept-Encoding: gzip, deflate。Server能夠向支持gzip/deflate的瀏覽器返回經gzip或者deflate編碼的HTML頁面。 許多情形下這可以減少5到10倍的下載時間,也節省帶寬。
Accept-Language:
作用: 瀏覽器申明自己接收的語言。
語言跟字符集的區別:中文是語言,中文有多種字符集,比如big5,gb2312,gbk等等;
例如: Accept-Language:zh-cn 。如果請求消息中沒有設置這個報頭域,服務器假定客戶端對各種語言都可以接受。
User-Agent:
作用:告訴HTTP服務器, 客戶端使用的操作系統和瀏覽器的名稱和版本.
我們上網登陸論壇的時候,往往會看到一些歡迎信息,其中列出了你的操作系統的名稱和版本,你所使用的瀏覽器的名稱和版本,這往往讓很多人感到很神 奇,實際上, 服務器應用程序就是從User-Agent這個請求報頭域中獲取到這些信息User-Agent請求報頭域允許客戶端將它的操作系統、瀏覽 器和其它屬性告訴服務器。
例如: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; CIBA; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET4.0C; InfoPath.2; .NET4.0E)
Accept-Charset:
作用:瀏覽器申明自己接收的字符集,這就是本文前面介紹的各種字符集和字符編碼,如gb2312,utf-8(通常我們說Charset包括了相應的字符編碼方案);
例如:Accept-Charset:iso-8859-1,gb2312.如果在請求消息中沒有設置這個域,缺省是任何字符集都可以接受。
Authorization:授權信息,通常出現在對服務器發送的WWW-Authenticate頭的應答中;
Authorization請求報頭域主要用于證明客戶端有權查看某個資源。當瀏覽器訪問一個頁面時,如果收到服務器的響應代碼為401(未授權),可以發送一個包含Authorization請求報頭域的請求,要求服務器對其進行驗證。
Cookie/Login 頭域
Cookie:
作用: 最重要的header, 將cookie的值發送給HTTP 服務器
Entity頭域
Content-Length
作用:發送給HTTP服務器數據的長度。即請求消息正文的長度;
例如: Content-Length: 38
Content-Type:
作用:
例如:Content-Type: application/x-www-form-urlencoded
Miscellaneous 頭域
Referer:
作用: 提供了Request的上下文信息的服務器,告訴服務器我是從哪個鏈接過來的,比如從我主頁上鏈接到一個朋友那里, 他的服務器就能夠從HTTP Referer中統計出每天有多少用戶點擊我主頁上的鏈接訪問 他的網站。
例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
Cache 頭域
If-Modified-Since:
作用: 把瀏覽器端緩存頁面的最后修改時間發送到服務器去,服務器會把這個時間與服務器上實際文件的最后修改時間進行對比。如果時間一致,那么返回304,客戶端 就直接使用本地緩存文件。如果時間不一致,就會返回200和新的文件內容。客戶端接到之后,會丟棄舊文件,把新文件緩存起來,并顯示在瀏覽器中。
例如:If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT。
If-None-Match:
作用: If-None-Match和ETag一起工作,工作原理是在HTTP Response中添加ETag信息。 當用戶再次請求該資源時,將在HTTP Request 中加入If-None-Match信息(ETag的值)。如果服務器驗證資源的ETag沒有改變(該資源沒有更新),將返回一個304狀態告訴客戶端使用 本地緩存文件。否則將返回200狀態和新的資源和Etag. 使用這樣的機制將提高網站的性能
例如: If-None-Match: "03f2b33c0bfcc1:0"
Pragma:
作用: 防止頁面被緩存, 在HTTP/1.1版本中,它和Cache-Control:no-cache作用一模一樣
Pargma只有一個用法, 例如: Pragma: no-cache
注意: 在HTTP/1.0版本中,只實現了Pragema:no-cache, 沒有實現Cache-Control
Cache-Control:
作用: 這個是非常重要的規則。 這個用來指定Response-Request遵循的緩存機制。各個指令含義如下
Cache-Control:Public 可以被任何緩存所緩存()
Cache-Control:Private 內容只緩存到私有緩存中
Cache-Control:no-cache 所有內容都不會被緩存
2. HTTP響應格式
在接收和解釋請求消息后,服務器會返回一個 HTTP 響應消息。與 HTTP 請求類似,HTTP 響應也是由三個部分組成,分別是:狀態行、消息報頭和響應正文。如:
HTTP/1.1 200 OK
Date: Sun, 17 Mar 2013 08:12:54 GMT
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
<html>
<head>
<title>HTTP響應示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
1、狀態行
狀態行由協議版本、數字形式的狀態代碼,及相應的狀態描述組成,各元素之間以空格分隔,結尾時回車換行符,格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
HTTP-Version 表示服務器 HTTP 協議的版本,Status-Code 表示服務器發回的響應代碼,Reason-Phrase 表示狀態代碼的文本描述,CRLF 表示回車換行。例如:
HTTP/1.1 200 OK (CRLF)
狀態代碼與狀態描述
狀態代碼由 3 位數字組成, 表示請求是否被理解或被滿足,狀態描述給出了關于狀態碼的簡短的文字描述。狀態碼的第一個數字定義了響應類別,后面兩位數字沒有具體分類。第一個數字有 5 種取值,如下所示。
常見狀態代碼、狀態描述、說明:
200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤,不能被服務器所理解
401 Unauthorized //請求未經授權,這個狀態代碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden //服務器收到請求,但是拒絕提供服務
404 Not Found //請求資源不存在,eg:輸入了錯誤的URL
500 Internal Server Error //服務器發生不可預期的錯誤
503 Server Unavailable //服務器當前不能處理客戶端的請求,一段時間后可能恢復正常
2、響應正文
響應正文就是服務器返回的資源的內容,響應頭和正文之間也必須用空行分隔。如:
3 、響應頭信息
HTTP最常見的響應頭如下所示:
Cache頭域
Date:
作用:生成消息的具體時間和日期,即當前的GMT時間。
例如: Date: Sun, 17 Mar 2013 08:12:54 GMT
Expires:
作用: 瀏覽器會在指定過期時間內使用本地緩存,指明應該在什么時候認為文檔已經過期,從而不再緩存它。
例如: Expires: Thu, 19 Nov 1981 08:52:00 GMT
Vary
作用:
例如: Vary: Accept-Encoding
Cookie/Login 頭域
P3P
作用: 用于跨域設置Cookie, 這樣可以解決iframe跨域訪問cookie的問題
例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR
Set-Cookie
作用: 非常重要的header, 用于把cookie 發送到客戶端瀏覽器, 每一個寫入cookie都會生成一個Set-Cookie.
例如: Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Entity實體頭域:
實體內容的屬性,包括實體信息類型,長度,壓縮方法,最后一次修改時間,數據有效性等。
ETag:
作用: 和If-None-Match 配合使用。 (實例請看上節中If-None-Match的實例)
例如: ETag: "03f2b33c0bfcc1:0"
Last-Modified:
作用: 用于指示資源的最后修改日期和時間。(實例請看上節的If-Modified-Since的實例)
例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT
Content-Type:
作用:WEB服務器告訴瀏覽器自己響應的對象的類型和字符集,
例如:
Content-Type: text/html; charset=utf-8
Content-Type:text/html;charset=GB2312
Content-Type: image/jpeg
Content-Length:
指明實體正文的長度,以字節方式存儲的十進制數字來表示。在數據下行的過程中,Content-Length的方式要預先在服務器中緩存所有數據,然后所有數據再一股腦兒地發給客戶端。
例如: Content-Length: 19847
Content-Encoding:
作用:文檔的編碼(Encode)方法。一般是壓縮方式。
WEB服務器表明自己使用了什么壓縮方法(gzip,deflate)壓縮響應中的對象。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。
例如:Content-Encoding:gzip
Content-Language:
作用: WEB服務器告訴瀏覽器自己響應的對象的語言者
例如: Content-Language:da
Miscellaneous 頭域
Server:
作用:指明HTTP服務器的軟件信息
例如:Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By:
作用:表示網站是用什么技術開發的
例如: X-Powered-By: PHP/5.2.5
Transport頭域
Connection:
例如: Connection: keep-alive 當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接
例如: Connection: close 代表一個Request完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接會關閉, 當客戶端再次發送Request,需要重新建立TCP連接。
Location頭域
Location:
作用: 用于重定向一個新的位置, 包含新的URL地址
實例請看304狀態實例
HTTP協議是無狀態的和Connection: keep-alive的區別
無狀態是指協議對于事務處理沒有記憶能力,服務器不知道客戶端是什么狀態。從另一方面講,打開一個服務器上的網頁和你之前打開這個服務器上的網頁之間沒有任何聯系。
HTTP是一個無狀態的面向連接的協議,無狀態不代表HTTP不能保持TCP連接,更不能代表HTTP使用的是UDP協議(無連接)。
從HTTP/1.1起,默認都開啟了Keep-Alive,保持連接特性,簡單地說,當一個網頁打開完成后,客戶端和服務器之間用于傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的網頁,會繼續使用這一條已經建立的連接。
Keep-Alive不會永久保持連接,它有一個保持時間,可以在不同的服務器軟件(如Apache)中設定這個時間。
3. 瀏覽器緩存
瀏覽器緩存:包括頁面html緩存和圖片js,css等資源的緩存。如下圖,瀏覽器緩存是基于把頁面信息保存到用戶本地電腦硬盤里。
1、緩存的優點:
1)服務器響應更快:因為請求從緩存服務器(離客戶端更近)而不是源服務器被相應,這個過程耗時更少,讓服務器看上去響應更快。
2)減少網絡帶寬消耗:當副本被重用時會減低客戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長并更易于管理。
2、緩存工作原理
頁面緩存狀態是由http header決定的,一個瀏覽器請求信息,一個是服務器響應信息。主要包括Pragma: no-cache、Cache-Control、 Expires、 Last-Modified、If-Modified-Since。其中Pragma: no-cache由HTTP/1.0規定,Cache-Control由HTTP/1.1規定。
工作原理圖:
從圖中我們可以看到原理主要分三步:
與緩存相關的HTTP擴展消息頭
Expires:設置頁面過期時間,格林威治時間GMT
Cache-Control:更細致的控制緩存的內容
Last-Modified:請求對象最后一次的修改時間 用來判斷緩存是否過期 通常由文件的時間信息產生
ETag:響應中資源的校驗值,在服務器上某個時段是唯一標識的。ETag是一個可以 與Web資源關聯的記號(token),和Last-Modified功能才不多,也是一個標識符,一般和Last-Modified一起使用,加強服務器判斷的準確度。
Date:服務器的時間
If-Modified-Since:客戶端存取的該資源最后一次修改的時間,用來和服務器端的Last-Modified做比較
If-None-Match:客戶端存取的該資源的檢驗值,同ETag。
Cache-Control的主要參數
Cache-Control: private/public Public 響應會被緩存,并且在多用戶間共享。 Private 響應只能夠作為私有的緩存,不能再用戶間共享。
Cache-Control: no-cache:不進行緩存
Cache-Control: max-age=x:緩存時間 以秒為單位
Cache-Control: must-revalidate:如果頁面是過期的 則去服務器進行獲取。
2、關于圖片,css,js,flash的緩存
這個主要通過服務器的配置來實現這個技術,如果使用apache服務器的話,可以使用mod_expires模塊來實現:
編譯mod_expires模塊:
Cd /root/httpd-2.2.3/modules/metadata
/usr/local/apache/bin/apxs -i -a -c mod_expires.c //編譯
編輯httpd.conf配置:添加下面內容
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
ExpiresByType text/html "access plus 1 months"
ExpiresByType text/css "access plus 1 months"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpeg "access plus 1 months"
ExpiresByType image/jpg "access plus 1 months"
ExpiresByType image/png "access plus 1 months"
EXpiresByType application/x-shockwave-flash "access plus 1 months"
EXpiresByType application/x-javascript "access plus 1 months"
#ExpiresByType video/x-flv "access plus 1 months"
</IfModule>
解釋:第一句--開啟服務
第二句--默認時間是一個月
在下面是關于各種類型的資源的緩存時間設置
瀏覽器根據訪問的域名找到其IP地址。DNS查找過程如下:
瀏覽器緩存:首先搜索瀏覽器自身的DNS緩存(緩存的時間比較短,大概只有1分鐘,且只能容納1000條緩存),看自身的緩存中是否是有域名對應的條目,而且沒有過期,如果有且沒有過期則解析到此結束。
系統緩存:如果瀏覽器自身的緩存里面沒有找到對應的條目,那么瀏覽器會搜索操作系統自身的DNS緩存,如果找到且沒有過期則停止搜索解析到此結束。
路由器緩存:如果系統緩存也沒有找到,則會向路由器發送查詢請求。
ISP(互聯網服務提供商) DNS緩存:如果在路由緩存也沒找到,最后要查的就是ISP緩存DNS的服務器。
TCP的3次握手。
一個HTTP請求報文由請求行(request line)、請求頭部(headers)、空行(blank line)和請求數據(request body)4個部分組成。
圖1 HTTP請求格式
1.3.1 請求行
請求行分為三個部分:請求方法、請求地址URL和HTTP協議版本,它們之間用空格分割。例如,GET /index.html HTTP/1.1。
1.請求方法
HTTP/1.1 定義的請求方法有8種:GET(完整請求一個資源)、POST(提交表單)、PUT(上傳文件)、DELETE(刪除)、PATCH、HEAD(僅請求響應首部)、OPTIONS(返回請求的資源所支持的方法)、TRACE(追求一個資源請求中間所經過的代理)。最常的兩種GET和POST,如果是RESTful接口的話一般會用到GET、POST、DELETE、PUT。
(1)GET
當客戶端要從服務器中讀取文檔時,當點擊網頁上的鏈接或者通過在瀏覽器的地址欄輸入網址來瀏覽網頁的,使用的都是GET方式。GET方法要求服務器將URL定位的資源放在響應報文的數據部分,會送給客戶端。
使用GET方法時,請求參數和對應的值附加在URL后面,利用一個問號‘?’代表URL的結尾與請求參數的開始,傳遞參數長度受限制。例如,/index.jsp?id=100&op=bind。通過GET方式傳遞的數據直接放在地址中,所以GET方式的請求一般不包含“請求內容”部分,請求數據以地址的形式表現在請求行。
地址中‘?’之后的部分就是通過GET發送的請求數據,各個數據之間用‘&’符號隔開。顯然這種方式不適合傳送私密數據。另外,由于不同的瀏覽器對地址的字符限制也有所不同,一般最多只能識別1024個字符,所以如果需要傳送大量數據的時候,也不適合使用GET方式。如果數據是英文字母/數字,原樣發送;如果是空格,轉換為+;如果是中文/其他字符,則直接把字符串用BASE64加密,得出:%E4%BD%A0%E5%A5%BD,其中%XX中的XX為該符號以16進制表示的ASCII。
(2)POST
允許客戶端給服務器提供信息較多。POST方法將請求參數封裝在HTTP請求數據中,以名稱/值的形式出現,可以傳輸大量數據,這樣POST方式對傳送的數據大小沒有限制,而且也不會顯示在URL中。POST方式請求行中不包含數據字符串,這些數據保存在“請求內容”部分,各數據之間也是使用‘&’符號隔開。POST方式大多用于頁面的表單中。因為POST也能完成GET的功能,因此多數人在設計表單的時候一律都使用POST方式,其實這是一個誤區。GET方式也有自己的特點和優勢,我們應該根據不同的情況來選擇是使用GET還是使用POST。
圖2 HTTP請求方法
2.URL
URL:統一資源定位符,是一種資源位置的抽象唯一識別方法。
組成:<協議>://<主機>:<端口>/<路徑>
端口和路徑有事可以省略(HTTP默認端口號是80)
3.協議版本
協議版本的格式為:HTTP/主版本號.次版本號,常用的有HTTP/1.0和HTTP/1.1
1.3.2 請求頭部
請求頭部為請求報文添加了一些附加信息,由“名/值”對組成,每行一對,名和值之間使用冒號分隔。
請求頭部的最后會有一個空行,表示請求頭部結束,接下來為請求數據。
1.3.3 請求數據
請求數據不在GET方法中使用,而在POST方法中使用。POST方法適用于需要客戶填寫表單的場合。與請求數據相關的最長使用的請求頭部是Cntent-Type和Content-Length。下面是一個POST方法的請求報文:
POST /index.php HTTP/1.1 請求行
Host: localhost
User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2請求頭
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer: http://localhost/
Content-Length:25
Content-Type:application/x-www-form-urlencoded
空行
username=aa&password=1234 請求數據
HTTP響應報文由狀態行(status line)、相應頭部(headers)、空行(blank line)和響應數據(response body)4個部分組成。
1.4.1 狀態行
狀態行由3部分組成,分別為:協議版本、狀態碼、狀態碼掃描。其中協議版本與請求報文一致,狀態碼描述是對狀態碼的簡單描述。
1.4.2 響應頭部
1.4.3 響應數據
用于存放需要返回給客戶端的數據信息。
HTTP/1.1 200 OK 狀態行
Date: Sun, 17 Mar 2013 08:12:54 GMT 響應頭部
Server: Apache/2.2.8 (Win32) PHP/5.2.5
X-Powered-By: PHP/5.2.5
Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 4393
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=utf-8
空行
<html> 響應數據
<head>
<title>HTTP響應示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
瀏覽器拿到HTML文件后,開始解析HTML代碼,遇到靜態資源時,就向服務器端去請求下載。
瀏覽器利用自己內部的工作機制,把請求到的靜態資源和HTML代碼進行渲染,呈現給用戶。
來源:CSDN
*請認真填寫需求信息,我們會在24小時內與您取得聯系。