HTTP協議
簡介
超文本傳輸協議(HypertextTransfer Protocol,簡稱HTTP)是應用層協議。HTTP 是一種請求/響應式的協議,即一個客戶端與服務器建立連接后,向服務器發送一個請求;服務器接到請求后,給予相應的響應信息。
HTTP在TCP/IP協議棧中的位置
HTTP協議通常承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示:
默認HTTP的端口號為80,HTTPS的端口號為443。
HTTP 請求報文
HTTP 請求報文由請求行、請求頭部、空行和請求包體 4 個部分組成,如下圖所示:
下面對請求報文格式進行簡單的分析:
1. 請求行:請求行由方法字段、URL 字段 和HTTP 協議版本字段 3 個部分組成,他們之間使用空格隔開。常用的 HTTP 請求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT;
- GET:當客戶端要從服務器中讀取某個資源時,使用GET 方法。GET 方法要求服務器將URL 定位的資源放在響應報文的數據部分,回送給客戶端,即向服務器請求某個資源。使用GET 方法時,請求參數和對應的值附加在 URL 后面,利用一個問號(“?”)代表URL 的結尾與請求參數的開始,傳遞參數長度受限制。例如,/index.jsp?id=100&op=bind。
- POST:當客戶端給服務器提供信息較多時可以使用POST 方法,POST 方法向服務器提交數據,比如完成表單數據的提交,將數據提交給服務器處理。GET 一般用於獲取/查詢資源信息,POST 會附帶用戶數據,一般用於更新資源信息。POST 方法將請求參數封裝在HTTP 請求數據中,以名稱/值的形式出現,可以傳輸大量數據;
2. 請求頭部:請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。請求頭部通知服務器有關於客戶端請求的信息,典型的請求頭有:
- User-Agent:產生請求的瀏覽器類型;
- Accept:客戶端可識別的響應內容類型列表;星號 “ * ” 用於按范圍將類型分組,用 “ */* ” 指示可接受全部類型,用“ type/* ”指示可接受 type 類型的所有子類型;
- Accept-Language:客戶端可接受的自然語言;
- Accept-Encoding:客戶端可接受的編碼壓縮格式;
- Accept-Charset:可接受的應答的字符集;
- Host:請求的主機名,允許多個域名同處一個IP 地址,即虛擬主機;
- connection:連接方式(close 或 keepalive);
- Cookie:存儲於客戶端擴展字段,向同一域名的服務端發送屬於該域的cookie;
- ……
3. 空行:最后一個請求頭之后是一個空行,發送回車符和換行符,通知服務器以下不再有請求頭;
4. 請求包體:請求包體不在 GET 方法中使用,而是在POST 方法中使用。POST 方法適用於需要客戶填寫表單的場合。與請求包體相關的最常使用的是包體類型 Content-Type 和包體長度 Content-Length;
HTTP 響應報文
HTTP 響應報文由狀態行、響應頭部、空行和響應包體 4 個部分組成,如下圖所示:
下面對響應報文格式進行簡單的分析:
1. 狀態行:狀態行由 HTTP 協議版本字段、狀態碼和狀態碼的描述文本 3 個部分組成,他們之間使用空格隔開;
a) 狀態碼由三位數字組成,第一位數字表示響應的類型,常用的狀態碼有五大類如下所示:
- 1xx:表示服務器已接收了客戶端請求,客戶端可繼續發送請求;
- 2xx:表示服務器已成功接收到請求並進行處理;
- 3xx:表示服務器要求客戶端重定向;
- 4xx:表示客戶端的請求有非法內容;
- 5xx:表示服務器未能正常處理客戶端的請求而出現意外錯誤
b) 狀態碼描述文本有如下取值:
- 200 OK:表示客戶端請求成功;
- 400 Bad Request:表示客戶端請求有語法錯誤,不能被服務器所理解;
- 401 Unauthonzed:表示請求未經授權,該狀態代碼必須與 WWW-Authenticate 報頭域一起使用;
- 403 Forbidden:表示服務器收到請求,但是拒絕提供服務,通常會在響應正文中給出不提供服務的原因;
- 404 Not Found:請求的資源不存在,例如,輸入了錯誤的URL;
- 500 InternalServer Error:表示服務器發生不可預期的錯誤,導致無法完成客戶端的請求;
- 503 ServiceUnavailable:表示服務器當前不能夠處理客戶端的請求,在一段時間之后,服務器可能會恢復正常;
2. 響應頭部:響應頭可能包括:
1) Location:Location響應報頭域用於重定向接受者到一個新的位置。例如:客戶端所請求的頁面已不存在原先的位置,為了讓客戶端重定向到這個頁面新的位置,服務器端可以發回Location響應報頭后使用重定向語句,讓客戶端去訪問新的域名所對應的服務器上的資源;
2) Server:Server 響應報頭域包含了服務器用來處理請求的軟件信息及其版本。它和 User-Agent 請求報頭域是相對應的,前者發送服務器端軟件的信息,后者發送客戶端軟件(瀏覽器)和操作系統的信息。
3) Vary:指示不可緩存的請求頭列表;
4) Connection:連接方式;
a) 對於請求來說:close(告訴 WEB 服務器或者代理服務器,在完成本次請求的響應后,斷開連接,不等待本次連接的后續請求了)。keepalive(告訴WEB服務器或者代理服務器,在完成本次請求的響應后,保持連接,等待本次連接的后續請求);
b) 對於響應來說:close(連接已經關閉); keepalive(連接保持着,在等待本次連接的后續請求); Keep-Alive:如果瀏覽器請求保持連接,則該頭部表明希望WEB 服務器保持連接多長時間(秒);例如:Keep-Alive:300;
5) WWW-Authenticate:WWW-Authenticate響應報頭域必須被包含在401 (未授權的)響應消息中,這個報頭域和前面講到的Authorization 請求報頭域是相關的,當客戶端收到 401 響應消息,就要決定是否請求服務器對其進行驗證。如果要求服務器對其進行驗證,就可以發送一個包含了Authorization 報頭域的請求;
3. 空行:最后一個響應頭部之后是一個空行,發送回車符和換行符,通知服務器以下不再有響應頭部。
4. 響應包體:服務器返回給客戶端的文本信息;
HTTP 工作原理
HTTP 協議采用請求/響應模型。客戶端向服務器發送一個請求報文,服務器以一個狀態作為響應。
以下是 HTTP 請求/響應的步驟:
1. 客戶端連接到web服務器:HTTP 客戶端與web服務器建立一個 TCP 連接;
2. 客戶端向服務器發起 HTTP 請求:通過已建立的TCP 連接,客戶端向服務器發送一個請求報文;
3. 服務器接收 HTTP 請求並返回 HTTP 響應:服務器解析請求,定位請求資源,服務器將資源副本寫到 TCP 連接,由客戶端讀取;
4. 釋放 TCP 連接:若connection 模式為close,則服務器主動關閉TCP 連接,客戶端被動關閉連接,釋放TCP 連接;若connection 模式為keepalive,則該連接會保持一段時間,在該時間內可以繼續接收請求;
5. 客戶端瀏覽器解析HTML內容:客戶端將服務器響應的 html 文本解析並顯示;
例如:在瀏覽器地址欄鍵入URL,按下回車之后會經歷以下流程:
1. 瀏覽器向 DNS 服務器請求解析該 URL 中的域名所對應的 IP 地址;
2. 解析出 IP 地址后,根據該 IP 地址和默認端口 80,和服務器建立 TCP 連接;
3. 瀏覽器發出讀取文件(URL 中域名后面部分對應的文件)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的數據發送給服務器;
4. 服務器對瀏覽器請求作出響應,並把對應的 html 文本發送給瀏覽器;
5. 釋放 TCP 連接;
6. 瀏覽器將該 html 文本並顯示內容;
HTTP 無狀態性
HTTP 協議是無狀態的(stateless)。也就是說,同一個客戶端第二次訪問同一個服務器上的頁面時,服務器無法知道這個客戶端曾經訪問過,服務器也無法分辨不同的客戶端。HTTP 的無狀態特性簡化了服務器的設計,使服務器更容易支持大量並發的HTTP 請求。
HTTP 持久連接
HTTP1.0 使用的是非持久連接,主要缺點是客戶端必須為每一個待請求的對象建立並維護一個新的連接,即每請求一個文檔就要有兩倍RTT 的開銷。因為同一個頁面可能存在多個對象,所以非持久連接可能使一個頁面的下載變得十分緩慢,而且這種短連接增加了網絡傳輸的負擔。HTTP1.1 使用持久連接keepalive,所謂持久連接,就是服務器在發送響應后仍然在一段時間內保持這條連接,允許在同一個連接中存在多次數據請求和響應,即在持久連接情況下,服務器在發送完響應后並不關閉TCP 連接,而客戶端可以通過這個連接繼續請求其他對象。
HTTP/1.0 每次請求都需要建立新的TCP連接,連接不能復用。HTTP/1.1 新的請求可以在上次請求建立的TCP連接之上發送,連接可以復用。優點是減少重復進行TCP三次握手的開銷,提高效率。
Cookie和Session
Cookie和Session都為了用來保存狀態信息,都是保存客戶端狀態的機制,它們都是為了解決HTTP無狀態的問題而所做的努力。
Session可以用Cookie來實現,也可以用URL回寫的機制來實現。用Cookie來實現的Session可以認為是對Cookie更高級的應用。
Cookie和Session的比較
Cookie和Session有以下明顯的不同點:
1)Cookie將狀態保存在客戶端,Session將狀態保存在服務器端;
2)Cookies是服務器在本地機器上存儲的小段文本並隨每一個請求發送至同一個服務器。Cookie最早在RFC2109中實現,后續RFC2965做了增強。網絡服務器用HTTP頭向客戶端發送cookies,在客戶終端,瀏覽器解析這些cookies並將它們保存為一個本地文件,它會自動將同一服務器的任何請求縛上這些cookies。Session並沒有在HTTP的協議中定義;
3)Session是針對每一個用戶的,變量的值保存在服務器上,用一個sessionID來區分是哪個用戶session變量,這個值是通過用戶的瀏覽器在訪問的時候返回給服務器,當客戶禁用cookie時,這個值也可能設置為由get來返回給服務器;
4)就安全性來說:當你訪問一個使用session 的站點,同時在自己機子上建立一個cookie,建議在服務器端的SESSION機制更安全些.因為它不會任意讀取客戶存儲的信息。
Session機制
Session機制是一種服務器端的機制,服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session的時候,服務器首先檢查這個客戶端的請求里是否已包含了一個session標識 - 稱為 session id,如果已包含一個session id則說明以前已經為此客戶端創建過session,服務器就按照session id把這個 session檢索出來使用(如果檢索不到,可能會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session並且生成一個與此session相關聯的session id,session id的值應該是一個既不會重復,又不容易被找到規律以仿造的字符串,這個 session id將被在本次響應中返回給客戶端保存。
Session的實現方式
1、 使用Cookie來實現
服務器給每個Session分配一個唯一的JSESSIONID,並通過Cookie發送給客戶端。
當客戶端發起新的請求的時候,將在Cookie頭中攜帶這個JSESSIONID。這樣服務器能夠找到這個客戶端對應的Session。
流程如下圖所示:
2、 使用URL回寫來實現
URL回寫是指服務器在發送給瀏覽器頁面的所有鏈接中都攜帶JSESSIONID的參數,這樣客戶端點擊任何一個鏈接都會把JSESSIONID帶回服務器。
如果直接在瀏覽器輸入服務端資源的url來請求該資源,那么Session是匹配不到的。
Tomcat對Session的實現,是一開始同時使用Cookie和URL回寫機制,如果發現客戶端支持Cookie,就繼續使用Cookie,停止使用URL回寫。如果發現Cookie被禁用,就一直使用URL回寫。jsp開發處理到Session的時候,對頁面中的鏈接記得使用response.encodeURL() 。
1)Session超時:Session在指定時間內失效,例如30分鍾,若在30分鍾內沒有操作,則Session會失效,例如在web.xml中進行了如下設置:
<session-config>
<session-timeout>30</session-timeout> //單位:分鍾
</session-config>
2)使用session.invalidate()明確的去掉Session。
4、與Cookie相關的HTTP擴展頭
1)Cookie:客戶端將服務器設置的Cookie返回到服務器;
2)Set-Cookie:服務器向客戶端設置Cookie;
3)Cookie2 (RFC2965)):客戶端指示服務器支持Cookie的版本;
4)Set-Cookie2 (RFC2965):服務器向客戶端設置Cookie。
5、Cookie的流程
服務器在響應消息中用Set-Cookie頭將Cookie的內容回送給客戶端,客戶端在新的請求中將相同的內容攜帶在Cookie頭中發送給服務器。從而實現會話的保持。
流程如下圖所示:
緩存的實現原理
1、什么是Web緩存
WEB緩存(cache)位於Web服務器和客戶端之間。
緩存會根據請求保存輸出內容的副本,例如html頁面,圖片,文件,當下一個請求來到的時候:如果是相同的URL,緩存直接使用副本響應訪問請求,而不是向源服務器再次發送請求。
HTTP協議定義了相關的消息頭來使WEB緩存盡可能好的工作。
2、緩存的優點
1) 減少相應延遲:因為請求從緩存服務器(離客戶端更近)而不是源服務器被相應,這個過程耗時更少,讓web服務器看上去相應更快。
2) 減少網絡帶寬消耗:當副本被重用時會減低客戶端的帶寬消耗;客戶可以節省帶寬費用,控制帶寬的需求的增長並更易於管理。
3、與緩存相關的HTTP擴展消息頭
1) Expires:指示響應內容過期的時間,格林威治時間GMT
2) Cache-Control:更細致的控制緩存的內容
3) Last-Modified:響應中資源最后一次修改的時間
4) ETag:響應中資源的校驗值,在服務器上某個時段是唯一標識的。
5) Date:服務器的時間
6) If-Modified-Since:客戶端存取的該資源最后一次修改的時間,同Last-Modified。
7) If-None-Match:客戶端存取的該資源的檢驗值,同ETag。
4、客戶端緩存生效的常見流程
服務器收到請求時,會在200OK中回送該資源的Last-Modified和ETag頭,客戶端將該資源保存在cache中,並記錄這兩個屬性。當客戶端需要發送相同的請求時,會在請求中攜帶If-Modified-Since和If-None-Match兩個頭。兩個頭的值分別是響應中Last-Modified和ETag頭的值。服務器通過這兩個頭判斷本地資源未發生變化,客戶端不需要重新下載,返回304響應。常見流程如下圖所示:
5、Web緩存機制
HTTP/1.1中緩存的目的是為了在很多情況下減少發送請求,同時在許多情況下可以不需要發送完整響應。前者減少了網絡回路的數量;HTTP利用一個“過期(expiration)”機制來為此目的。后者減少了網絡應用的帶寬;HTTP用“驗證(validation)”機制來為此目的。
HTTP定義了3種緩存機制:
1)Freshness:允許一個回應消息可以在源服務器不被重新檢查,並且可以由服務器和客戶端來控制。例如,Expires回應頭給了一個文檔不可用的時間。Cache-Control中的max-age標識指明了緩存的最長時間;
2)Validation:用來檢查以一個緩存的回應是否仍然可用。例如,如果一個回應有一個Last-Modified回應頭,緩存能夠使用If-Modified-Since來判斷是否已改變,以便判斷根據情況發送請求;
3)Invalidation: 在另一個請求通過緩存的時候,常常有一個副作用。例如,如果一個URL關聯到一個緩存回應,但是其后跟着POST、PUT和DELETE的請求的話,緩存就會過期。
斷點續傳和多線程下載的實現原理
1) HTTP協議的GET方法,支持只請求某個資源的某一部分;
2) 206 Partial Content 部分內容響應;
3) Range 請求的資源范圍;
4) Content-Range 響應的資源范圍;
5) 在連接斷開重連時,客戶端只請求該資源未下載的部分,而不是重新請求整個資源,來實現斷點續傳。
分塊請求資源實例:
Eg1:Range:bytes=306302- :請求這個資源從306302個字節到末尾的部分;
Eg2:Content-Range: bytes306302-604047/604048:響應中指示攜帶的是該資源的第306302-604047的字節,該資源共604048個字節;
客戶端通過並發的請求相同資源的不同片段,來實現對某個資源的並發分塊下載。從而達到快速下載的目的。目前流行的FlashGet和迅雷基本都是這個原理。
多線程下載的原理:
1) 下載工具開啟多個發出HTTP請求的線程;
2) 每個http請求只請求資源文件的一部分:Content-Range: bytes 20000-40000/47000;
3) 合並每個線程下載的文件。
http代理
http代理服務器
代理服務器英文全稱是ProxyServer,其功能就是代理網絡用戶去取得網絡信息。形象的說:它是網絡信息的中轉站。
代理服務器是介於瀏覽器和Web服務器之間的一台服務器,有了它之后,瀏覽器不是直接到Web服務器去取回網頁而是向代理服務器發出請求,Request信號會先送到代理服務器,由代理服務器來取回瀏覽器所需要的信息並傳送給你的瀏覽器。而且,大部分代理服務器都具有緩沖的功能,就好象一個大的Cache,它有很大的存儲空間,它不斷將新取得數據儲存到它本機的存儲器上,如果瀏覽器所請求的數據在它本機的存儲器上已經存在而且是最新的,那么它就不重新從Web服務器取數據,而直接將存儲器上的數據傳送給用戶的瀏覽器,這樣就能顯著提高瀏覽速度和效率。
更重要的是:ProxyServer(代理服務器)是Internet鏈路級網關所提供的一種重要的安全功能,它的工作主要在開放系統互聯(OSI)模型的對話層。
http代理服務器的主要功能
主要功能如下:
1)突破自身IP訪問限制,訪問國外站點。如:教育網、169網等網絡用戶可以通過代理訪問國外網站;
2)訪問一些單位或團體內部資源,如某大學FTP(前提是該代理地址在該資源的允許訪問范圍之內),使用教育網內地址段免費代理服務器,就可以用於對教育 網開放的各類FTP下載上傳,以及各類資料查詢共享等服務;
3)突破中國電信的IP封鎖:中國電信用戶有很多網站是被限制訪問的,這種限制是人為的,不同Serve對地址的封鎖是不同的。所以不能訪問時可以換一個國 外的代理服務器試試;
4)提高訪問速度:通常代理服務器都設置一個較大的硬盤緩沖區,當有外界的信息通過時,同時也將其保存到緩沖區中,當其他用戶再訪問相同的信息時, 則直接由緩沖區中取出信息,傳給用戶,以提高訪問速度;
5)隱藏真實IP:上網者也可以通過這種方法隱藏自己的IP,免受攻擊。
http代理圖示
http代理的圖示見下圖:
對於客戶端瀏覽器而言,http代理服務器相當於服務器。
而對於Web服務器而言,http代理服務器又擔當了客戶端的角色。
虛擬主機的實現
1、什么是虛擬主機
虛擬主機:是在網絡服務器上划分出一定的磁盤空間供用戶放置站點、應用組件等,提供必要的站點功能與數據存放、傳輸功能。
所謂虛擬主機,也叫“網站空間”就是把一台運行在互聯網上的服務器划分成多個“虛擬”的服務器,每一個虛擬主機都具有獨立的域名和完整的Internet服務器(支持WWW、FTP、E-mail等)功能。一台服務器上的不同虛擬主機是各自獨立的,並由用戶自行管理。但一台服務器主機只能夠支持一定數量的虛擬主機,當超過這個數量時,用戶將會感到性能急劇下降。
2、虛擬主機的實現原理
虛擬主機是用同一個WEB服務器,為不同域名網站提供服務的技術。Apache、Tomcat等均可通過配置實現這個功能。
相關的HTTP消息頭:Host。
例如:Host: www.baidu.com
客戶端發送HTTP請求的時候,會攜帶Host頭,Host頭記錄的是客戶端輸入的域名。這樣服務器可以根據Host頭確認客戶要訪問的是哪一個域名。