Http協議系列----OSI參考模型,協議原理構成,三次握手,四次揮手,連接管理

前言

這篇文章實話說我有點虛,因爲平時都不怎麽研究這一塊的,然後涉及到的知識點超多,我只能到處看看資料總結一下相關信息,所以在此我只想說句:
本文章內容只代表個人立場,有錯必改!
原本打算一次性總結,後來越扯越多超過字數限制了,就幹脆做成http系列文章了,不定時更新原有內容(發現哪裏出錯的話),不定時新增系列文章,請見諒!
Http協議系列----OSI參考模型,協議原理構成,三次握手,四次揮手,連接管理
Http協議系列—-字符編碼,cookie,緩存,疑難雜症

OSI參考模型(來自百度百科)

開始進入正題之前先插個知識點,讓大家對HTTP,TCP,UDP的底層構成有些抽象認識各負責什麽功能.
OSI(Open System Interconnect),即開放式系統互聯。該體系結構標准定義了網絡互連的七層框架(物理層、數據鏈路層、網絡層、傳輸層、會話層、表示層和應用層),即ISO開放系統互連參考模型。在這一框架下進一步詳細規定了每一層的功能,以實現開放系統環境中的互連性、互操作性和應用的可移植性。

  • 物理層(Physical Layer)
    物理層是OSI參考模型的最低層,它利用傳輸介質爲數據鏈路層提供物理連接。它主要關心的是通過物理鏈路從一個節點向另一個節點傳送比特流,物理鏈路可能是銅線、衛星、微波或其他的通訊媒介。它關心的問題有:多少伏電壓代表1?多少伏電壓代表0?時鍾速率是多少?采用全雙工還是半雙工傳輸?總的來說物理層關心的是鏈路的機械、電氣、功能和規程特性。
  • 數據鏈路層(Data Link Layer)
    數據鏈路層是爲網絡層提供服務的,解決兩個相鄰結點之間的通信問題,傳送的協議數據單元稱爲數據幀
    數據幀中包含物理地址(又稱MAC地址)、控制碼、數據及校驗碼等信息。該層的主要作用是通過校驗、確認和反饋重發等手段,將不可靠的物理鏈路轉換成對網絡層來說無差錯的數據鏈路。
    此外,數據鏈路層還要協調收發雙方的數據傳輸速率,即進行流量控制,以防止接收方因來不及處理發送方來的高速數據而導致緩衝器溢出及線路阻塞。
  • 網絡層(Network Layer)
    網絡層是爲傳輸層提供服務的,傳送的協議數據單元稱爲數據包或分組。該層的主要作用是解決如何使數據包通過各結點傳送的問題,即通過路徑選擇算法(路由)將數據包送到目的地。另外,爲避免通信子網中出現過多的數據包而造成網絡阻塞,需要對流入的數據包數量進行控制(擁塞控制)。當數據包要跨越多個通信子網才能到達目的地時,還要解決網際互連的問題。
  • 傳輸層(Transport Layer)
    傳輸層的作用是爲上層協議提供端到端的可靠和透明的數據傳輸服務,包括處理差錯控制和流量控制等問題。該層向高層屏蔽了下層數據通信的細節,使高層用戶看到的只是在兩個傳輸實體間的一條主機到主機的、可由用戶控制和設定的、可靠的數據通路。
    傳輸層傳送的協議數據單元稱爲段或報文。
  • 會話層(Session Layer)
    會話層主要功能是管理和協調不同主機上各種進程之間的通信(對話),即負責建立、管理和終止應用程序之間的會話。會話層得名的原因是它很類似于兩個實體間的會話概念。例如,一個交互的用戶會話以登錄到計算機開始,以注銷結束。
  • 表示層(Presentation Layer)
    表示層處理流經結點的數據編碼的表示方式問題,以保證一個系統應用層發出的信息可被另一系統的應用層讀出。如果必要,該層可提供一種標准表示形式,用于將計算機內部的多種數據表示格式轉換成網絡通信中采用的標准表示形式。數據壓縮和加密也是表示層可提供的轉換功能之一。
  • 應用層(Application Layer)
    應用層是OSI參考模型的最高層,是用戶與網絡的接口。該層通過應用程序來完成網絡用戶的應用需求,如文件傳輸、收發電子郵件等。

<br/>
具體通俗流程圖
圖片描述
(更多內容請自行查閱,本節到此爲止了.)

TCP/IP參考模型

當無線網絡和衛星出現以後,現有的協議在和它們相連的時候出現了問題,所以需要一種新的參考體系結構。這個體系結構在它的兩個主要協議出現以後,被稱爲TCP/IP參考模型(TCP/IP reference model)。
TCP/IP是一組用于實現網絡互連的通信協議。Internet網絡體系結構以TCP/IP爲核心。基于TCP/IP的參考模型將協議分成四個層次,它們分別是:網絡訪問層、網際互聯層、傳輸層(主機到主機)、和應用層

  • 網絡接入層(即主機-網絡層)
    網絡接入層與OSI參考模型中的物理層和數據鏈路層相對應。它負責監視數據在主機和網絡之間的交換。事實上,TCP/IP本身並未定義該層的協議,而由參與互連的各網絡使用自己的物理層和數據鏈路層協議,然後與TCP/IP的網絡接入層進行連接。地址解析協議(ARP)工作在此層,即OSI參考模型的數據鏈路層。
  • 網際互聯層
    網際互聯層對應于OSI參考模型的網絡層,主要解決主機到主機的通信問題。它所包含的協議設計數據包在整個網絡上的邏輯傳輸。注重重新賦予主機一個IP地址來完成對主機的尋址,它還負責數據包在多種網絡中的路由。該層有三個主要協議:網際協議(IP)、互聯網組管理協議(IGMP)和互聯網控制報文協議(ICMP)
    IP協議是網際互聯層最重要的協議,它提供的是一個可靠、無連接的數據報傳遞服務。
  • 傳輸層(Transport Layer)
    傳輸層對應于OSI參考模型的傳輸層,爲應用層實體提供端到端的通信功能,保證了數據包的順序傳送及數據的完整性。該層定義了兩個主要的協議:傳輸控制協議(TCP)和用戶數據報協議(UDP).
    TCP協議提供的是一種可靠的、通過“三次握手”來連接的數據傳輸服務;而UDP協議提供的則是不保證可靠的(並不是不可靠)、無連接的數據傳輸服務.
  • 應用層(Application Layer)
    應用層是OSI參考模型的最高層,是用戶與網絡的接口。該層通過應用程序來完成網絡用戶的應用需求,如文件傳輸、收發電子郵件等。

兩者主要區別在于: OSI參考模型雖然被看好,由于沒把握好時機,技術不成熟,實現困難;相反,TCP/IP參考模型雖然有許多不盡人意的地方,但還是比較成功的。
圖片描述
(還沒太懂也懶,直接百度圖片找張清晰的拿來用的..)
(更多內容請自行查閱,本節到此爲止了.)

TCP與UDP

TCP (Transmission Control Protocol)UDP(User Datagram Protocol)協議屬于傳輸層協議。其中TCP提供IP環境下的數據可靠傳輸,它提供的服務包括數據流傳送、可靠性、有效流控、全雙工操作和多路複用。通過面向連接、端到端和可靠的數據包發送。通俗說,它是事先爲所發送的數據開辟出連接好的通道,然後再進行數據發送;而UDP則不爲IP提供可靠性、流控或差錯恢複功能。一般來說,TCP對應的是可靠性要求高的應用,而UDP對應的則是可靠性要求低、傳輸經濟的應用。TCP支持的應用協議主要有:Telnet、FTP、SMTP等;UDP支持的應用層協議主要有:NFS(網絡文件系統)、SNMP(簡單網絡管理協議)、DNS(主域名稱系統)、TFTP(通用文件傳輸協議)等。

比較TCPUDP
是否面向連接
連接端點對點一對一,一對多,多對一和多對多的交互通信
模式流模式數據報模式
傳輸可靠性可靠非可靠
數據順序保證不保證
數據正確性保證可能丟包
速度

什麽是HTTP協議?(來自百度百科)

超文本傳輸協議(HTTP HyperText Transfer Protocol)是互聯網上應用最爲廣泛的一種網絡協議。所有的WWW文件都必須遵守這個標准。設計HTTP最初的目的是爲了提供一種發布和接收HTML頁面的方法,用于從WWW服務器傳輸超文本到本地浏覽器的傳輸協議。它可以使浏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先于圖形)等。

HTTP協議基本性質

  • 簡單
    HTTP報文能夠被人讀懂,還允許簡單測試,降低了門檻
  • 可擴展
    只要服務端和客戶端就新 headers 達成語義一致,新功能就可以被輕松加入進來
  • 無狀態,有會話
    1) 在同一個連接中,兩個執行成功的請求之間是沒有關系的。這就帶來了一個問題,用戶沒有辦法在同一個網站中進行連續的交互;
    2) HTTP的頭部擴展Cookies就可以解決這個問題,創建一個會話讓每次請求都能共享相同的上下文信息,達成相同的狀態;
  • 連接
    一個連接是由傳輸層來控制的,這從根本上不屬于HTTP的範圍。HTTP並不需要其底層的傳輸層協議是面向連接的,只需要它是可靠的,或不丟失消息的(至少返回錯誤)。

HTTP架構(來自百度百科)

HTTP是客戶端和服務端請求和應答的標准,之間可能隔著多個中間層。
通常,由HTTP客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的TCP連接。HTTP服務器則在那個端口監聽客戶端發送過來的請求。一旦收到請求,服務器(向客戶端)發回一個狀態行和(響應的)消息,消息的消息體可能是請求的文件、錯誤消息、或者其它一些信息。
HTTP使用TCP而不是UDP的原因在于(打開)一個網頁必須傳送很多數據,而TCP協議提供傳輸控制,按順序組織數據,和錯誤糾正。
通過HTTP或者HTTPS協議請求的資源由統一資源標示符(Uniform Resource Identifiers)(或者,更准確一些,URLs)來標識。

統一資源標示符URI(Uniform Resource Identifiers)

用于標識某一互聯網資源名稱的字符串。 該種標識允許用戶對任何(包括本地和互聯網)的資源(HTML文檔、圖像、視頻片段、程序等)通過特定的協議進行交互操作。
組成:(具體來源已經無法考察)
1)訪問資源的命名機制;
2)存放資源的主機名;
3)資源自身的名稱,由路徑表示,著重強調于資源;

URI又分成兩種:
一, 統一資源定位器URL(uniform resource locator)
URL是Internet上用來描述信息資源的字符串,主要用在各種WWW客戶程序和服務器程序上。
采用URL可以用一種統一的格式來描述各種信息資源,包括文件、服務器的地址和目錄等。
組成:
1)協議(或稱爲服務方式);
2)存有該資源的主機IP地址(有時也包括端口號);
3)主機資源的具體地址,如目錄和文件名等;
第一部分和第二部分之間用“://”符號隔開,第二部分和第三部分用“/”符號隔開。第一部分和第二部分是不可缺少的,第三部分有時可以省略。

二,統一資源命名URN(uniform resource name)
標識持久性 Internet 資源。
URN 可以提供一種機制,用于查找和檢索定義特定命名空間的架構文件。盡管普通的 URL 可以提供類似的功能,但是在這方面,URN 更加強大並且更容易管理,因爲 URN 可以引用多個 URL
URN是作爲特定內容的唯一名稱使用的,與當前資源的所在地無關。使用URN,就可以將資源四處遷移,而不用擔心遷移後無法訪問。

(更多內容請自行查閱,本節到此爲止了.)

工作原理(來自百度百科)

一次HTTP操作稱爲一個事務,其工作過程可分爲四步:

  • 首先客戶端與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作就開始了。
  • 建立連接後,客戶端發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。
  • 服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。
  • 客戶端接收服務器所返回的信息通過浏覽器顯示在用戶的顯示屏上,然後客戶端與服務器斷開連接

如果在以上過程中的某一步出現錯誤,那麽産生錯誤的信息將返回到客戶端,由顯示屏輸出。對于用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。
許多HTTP通訊是由一個用戶代理初始化的並且包括一個申請在源服務器上資源的請求。最簡單的情況可能是在用戶代理和服務器之間通過一個單獨的連接來完成。在Internet上,HTTP通訊通常發生在TCP/IP連接之上。缺省端口是TCP 80,但其它的端口也是可用的。但這並不預示著HTTP協議在Internet或其它網絡的其它協議之上才能完成。HTTP只預示著一個可靠的傳輸

建立連接 ---- 三次握手(three-way handshake)

所謂的“三次握手”即對每次發送的數據量是怎樣跟蹤進行協商使數據段的發送和接收同步,根據所接收到的數據量而確定的數據確認數及數據發送、接收完畢後何時撤消聯系,並建立虛連接。
爲了提供可靠的傳送,TCP在發送新的數據之前,以特定的順序將數據包的序號,並需要這些包傳送給目標機之後的確認消息。TCP總是用來發送大批量的數據。當應用程序在收到數據後要做出確認時也要用到TCP。

  • 第一次握手:建立連接時,客戶端發送syn包(syn=j)到服務器,並進入SYN_SENT狀態,等待服務器確認;
  • 第二次握手:服務器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也發送一個SYN包(syn=k),即SYN+ACK包,此時服務器進入SYN_RECV狀態
  • 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態,完成三次握手。

圖片描述
(還沒太懂也懶,直接百度圖片找張清晰的拿來用的..)

爲什麽需要三次握手(three-way handshake)呢?
有這樣一種情況下:客戶端發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以後的某個時間才到達服務器。本來這是一個早已失效的報文段。但服務器收到此失效的連接請求報文段後,就誤認爲是客戶端再次發出的一個新的連接請求。于是就向客戶端發出確認報文段,同意建立連接。假設不采用“三次握手”,那麽只要服務器發出確認,新的連接就建立了。由于現在客戶端並沒有發出建立連接的請求,因此不會理睬服務器的確認,也不會向服務器發送數據。但服務器卻以爲新的運輸連接已經建立,並一直等待客戶端發來數據。這樣,服務器的很多資源就白白浪費掉了。采用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,客戶端不會向服務器的確認發出確認。服務器于收不到確認,就知道客戶端並沒有要求建立連接。
總結而言:防止因爲特殊原因導致服務器接收到已失效的請求造成其一直在等待浪費資源.

術語

名稱描述
ACKacknowledgement 確認標志
FINfinish 結束標志
PSHpush 推標志
RSTreset 重置連接
URGurgent 緊急指針有效
SYNsynchronous 同步標志

了解到這我覺得就差不多了,再深我就看不懂了,有興趣的深入研究吧
(更多內容請自行查閱,本節到此爲止了.)

斷開連接 ---- 四次揮手(four-way handshake)

爲什麽建立連接要三次握手(three-way handshake)而斷開連接卻需要四次揮手(four-way handshake)?
這是因爲服務端的LISTEN狀態下的SOCKET當收到SYN報文的建連請求後,它可以把ACK和SYN(ACK起應答作用,而SYN起同步作用)放在一個報文裏來發送。但關閉連接時,當收到對方的FIN報文通知時,它僅僅表示對方沒有數據發送給你了;但未必你所有的數據都全部發送給對方了,所以你可以未必會馬上會關閉SOCKET,也即你可能還需要發送一些數據給對方之後,再發送FIN報文給對方來表示你同意現在可以關閉連接了,所以它這裏的ACK報文和FIN報文多數情況下都是分開發送的。

  • 當主機A的應用程序通知TCP數據已經發送完畢時,TCP向主機B發送一個帶有FIN附加標記的報文段;
  • 主機B收到這個FIN報文段之後,並不立即用FIN報文段回複主機A,而是先向主機A發送一個確認序號ACK,同時通知自己相應的應用程序:對方要求關閉連接(先發送ACK的目的是爲了防止在這段時間內,對方重傳FIN報文段);
  • 主機B的應用程序告訴TCP:我要徹底的關閉連接,TCP向主機A送一個FIN報文段;
  • 主機A收到這個FIN報文段後,向主機B發送一個ACK表示連接徹底釋放;

圖片描述
(還沒太懂也懶,直接百度圖片找張清晰的拿來用的..)
(更多內容請自行查閱,本節到此爲止了.)

HTTP請求(requests)

HTTP請求是由客戶端發出的消息,用來使服務器執行動作,主要包含三部分:

  • 請求行
    一, HTTP 方法
    1) 描述要執行的動作;

    二, 請求目標 (request target)
    通常是一個 URL,或者是協議、端口和域名的絕對路徑,通常以請求的環境爲特征。請求的格式因不同的 HTTP 方法而異.
    1) 一個絕對路徑,末尾跟上一個 ' ? ' 和查詢字符串;
    2) 一個完整的URL,被稱爲 絕對形式 (absolute form),主要在 GET 連接到代理時使用;
    3) 由域名和可選端口(以':'爲前綴)組成的 URL 的 authority component,稱爲 authority form。 僅在使用 CONNECT 建立 HTTP 隧道時才使用;
    4) 星號形式 (asterisk form),一個簡單的星號('*'),配合 OPTIONS 方法使用,代表整個服務器;

    三, HTTP 版本 (HTTP version)
    1) 定義了剩余報文的結構,作爲對期望的響應版本的指示符;

  • 請求頭
    不區分大小寫的字符串,緊跟著的冒號 (':') 和一個結構取決于 header 的值。 整個 header(包括值)由一行組成,這一行可以相當長。
    1, General headers,例如 Via,適用于整個報文;
    2, Request headers,例如 User-Agent,Accept-Type,通過進一步的定義(例如 Accept-Language),或者給定上下文(例如 Referer),或者進行有條件的限制 (例如 If-None) 來修改請求;
    3, Entity headers,例如 Content-Length,適用于請求的 body。顯然,如果請求中沒有任何 body,則不會發送這樣的頭文件;
  • 請求體
    不是所有的請求都有.
    1, Single-resource bodies,由一個單文件組成。該類型 body 由兩個 header 定義: Content-Type 和 Content-Length;
    2, Multiple-resource bodies,由多部分 body 組成,每一部分包含不同的信息位。通常是和 HTML Forms 連系在一起;
    圖片描述
    (這些簡單的東西我就懶得特意畫圖了,直接百度圖片找張清晰的拿來用的..)
    (更多內容請自行查閱,本節到此爲止了.)

HTTP響應(responses)

HTTP響應是服務器返回的消息,主要包含三部分:

  • 響應行
    一, 協議版本

    二, 狀態碼 (status code)
    表明請求是成功或失敗

    三, 狀態文本 (status text)
    一個簡短的,純粹的信息,通過狀態碼的文本描述,幫助人們理解該 HTTP 消息

  • 響應頭(同上)
  • 響應體(同上)
    圖片描述
    (這些簡單的東西我就懶得特意畫圖了,直接百度圖片找張清晰的拿來用的..)
    (更多內容請自行查閱,本節到此爲止了.)

請求方法

HTTP1.0定義了三種請求方法:GET, POSTHEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACECONNECT 方法。

方法描述
GET請求指定的頁面信息,並返回實體主體。
POST向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
HEAD類似于get請求,只不過返回的響應中沒有具體的內容,用于獲取報頭
OPTIONS允許客戶端查看服務器的性能。
PUT從客戶端向服務器傳送的數據取代指定的文檔的內容。
DELETE請求服務器刪除指定的頁面。
TRACE回顯服務器收到的請求,主要用于測試或診斷。
CONNECTHTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器

<br/>

有個很著名的經典問題,POST和GET的區別是什麽?

比較方面GETPOST
用法從服務器上獲取數據,不影響資源向服務器傳送數據,可能會導致新的資源的建立和/或已有資源的修改
傳輸方式將查詢字符串參數追加到url的末尾,只能ASCII 字符把數據作爲請求的主體提交,格式不限
大小根據URL而定,最大長度是 2048 個字符根據浏覽器而定,但比get大
安全性
服務器獲取方式Request.QueryStringRequest.Form
後退/刷新無害重新提交
曆史參數是否保留在浏覽器曆史中
書簽是否可收藏
是否能被緩存

HTTP消息頭

一個消息頭由不區分大小寫的名稱後跟一個冒號“:”,冒號後跟具體的值(不帶換行符)組成。該值前面的引導空白會被忽略。

  • 一般頭: 同時適用于請求和響應消息,但與最終消息主體中傳輸的數據無關的消息頭。
  • 請求頭: 包含有關要獲取的資源或客戶端本身更多信息的消息頭。
  • 響應頭: 包含有關服務器響應的補充信息,如其位置或服務器本身(名稱和版本等)的消息頭。
  • 實體頭: 包含有關實體主體的更多信息,比如主體長(Content-Length)度或其MIME類型。

常用標准頭

應答頭描述
Accept告訴服務端客戶端接受什麽類型的響應,可以爲一個或多個MIME類型的值.詳情Media type
Accept-Charset可以接受的字符集
Accept-Encoding可接受的編碼壓縮方法列表,詳情HTTP compression
Accept-Language允許客戶端聲明它可以理解的自然語言,以及優先選擇的區域方言。Content negotiation
Accept-Datetime設置接受的版本時間
Access-Control-Request-Method,Access-Control-Request-Headers發起一個與起源(下)的跨源資源共享的請求。詳情Cross-origin resource sharing
Allow服務器支持哪些請求方法
AuthorizationHTTP身份驗證的憑證
Content-Encoding文檔的編碼(Encode)方法。只有在解碼之後才可以得到Content-Type頭指定的內容類型。利用gzip壓縮文檔能夠顯著地減少HTML文檔的下載時間。Java的GZIPOutputStream可以很方便地進行gzip壓縮,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet應該通過查看Accept-Encoding頭(即request.getHeader("Accept-Encoding"))檢查浏覽器是否支持gzip,爲支持gzip的浏覽器返回經gzip壓縮的HTML頁面,爲其他浏覽器返回普通頁面。
Cache-Control這個字段用于指定所有緩存機制在整個請求/響應鏈中必須服從的指令。這些指令指定用于阻止緩存對請求或響應造成不利幹擾的行爲。這些指令通常覆蓋默認緩存算法。緩存指令是單向的,即請求中存在一個指令並不意味著響應中將存在同一個指令。詳情Cache-Control
Connection決定當前的事務完成後,是否會關閉網絡連接。如果該值是“keep-alive”,網絡連接就是持久的,不會關閉,使得對同一個服務器的請求可以繼續在該連接上完成。
Cookie一個請求首部,其中含有先前由服務器通過 Set-Cookie 首部投放並存儲到客戶端的 HTTP cookies。
Content-MD5設置基于MD5算法對請求體內容進行Base64二進制編碼
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來設置這個頭以避免轉換時間格式的麻煩。
Etag(Entity Tag)ETag一般不以明文形式相應給客戶端。在資源的各個生命周期中,它都具有不同的值,用于標識出資源的狀態。當資源發生變更時,如果其頭信息中一個或者多個發生變化,或者消息實體發生變化,那麽ETag也隨之發生變化.Etag由服務器端生成,客戶端通過If-Match或者說If-None-Match這個條件判斷請求來驗證資源是否修改。
Expect包含一個期望條件,表示服務器只有在滿足此期望條件的情況下才能妥善地處理請求。
Expires指定了一個日期/時間, 在這個日期/時間之後,HTTP響應被認爲是過時的;無效的日期,比如 0, 代表著一個過去的事件,即該資源已經過期了。如果還有一個 設置了 "max-age" 或者 "s-max-age" 指令的Cache-Control響應頭,那麽 Expires 頭就會被忽略。
Forwarded通過HTTP代理將客戶端連接到web服務器的原始信息公開。
Host服務器的域名(用于虛擬主機)和服務器監聽的TCP端口號。如果端口是請求服務的標准端口,則可以省略端口號。HTTP / 1.1以來的強制性。如果請求是直接在HTTP/2中生成的,則不應該使用它。
If-Modified-Since條件式請求首部,服務器只在所請求的資源在給定的日期時間之後對內容進行過修改的情況下才會將資源返回,狀態碼爲 200 。如果請求的資源從那時起未經修改,那麽返回一個不帶有消息主體的 304 響應,而在 Last-Modified 首部中會帶有上次修改時間。 不同于If-Unmodified-Since, If-Modified-Since 只可以用在 GET 或 HEAD 請求中。當與 If-None-Match 一同出現時,它會被忽略掉,除非服務器不支持 If-None-Match。
If-Match這是一個條件請求。在請求方法爲 GET 和 HEAD 的情況下,服務器僅在請求的資源滿足此首部列出的 ETag 之一時才會返回資源。而對于 PUT 或其他非安全方法來說,只有在滿足條件的情況下才可以將資源上傳。
If-None-Match條件式請求首部。對于 GETGET 和 HEAD 請求方法來說,當且僅當服務器上沒有任何資源的 ETag 屬性值與這個首部中列出的相匹配的時候,服務器端會才返回所請求的資源,響應碼爲 200 。對于其他方法來說,當且僅當最終確認沒有已存在的資源的 ETag 屬性值與這個首部中所列出的相匹配的時候,才會對請求進行相應的處理。詳情HTTP ETag
If-Range當字段值中的條件得到滿足時,Range 頭字段才會起作用,同時服務器回複206 部分內容狀態碼,以及Range 頭字段請求的相應部分;如果字段值中的條件沒有得到滿足,服務器將會返回 200 OK 狀態碼,並返回完整的請求資源。
If-Unmodified-Since使得當前請求成爲條件式請求:只有當資源在指定的時間之後沒有進行過修改的情況下,服務器才會返回請求的資源,或是接受 POST 或其他 non-safe 方法的請求。如果所請求的資源在指定的時間之後發生了修改,那麽會返回 412 (Precondition Failed) 錯誤。
Last-Modified文檔的最後改動時間。客戶可以通過If-Modified-Since請求頭提供一個日期,該請求將被視爲一個條件GET,只有改動時間遲于指定時間的文檔才會返回,否則返回一個304(Not Modified)狀態。Last-Modified也可用setDateHeader方法來設置。
Location表示客戶應當到哪裏去提取文檔。Location通常不是直接設置的,而是通過HttpServletResponse的sendRedirect方法,該方法同時設置狀態代碼爲302。
Max-Forwards限制消息可以通過代理或網關轉發的次數。
Origin發起對跨源資源共享的請求(請求服務器用于訪問控制-*響應字段)。
Proxy-Authorization用于連接到代理的授權憑據。
Refresh表示浏覽器應該在多少時間之後刷新文檔,以秒計。除了刷新當前文檔之外,你還可以通過setHeader("Refresh", "5; URL=http://host/path")讓浏覽器讀取指定的頁面。 注意這種功能通常是通過設置HTML頁面HEAD區的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">實現,這是因爲,自動刷新或重定向對于那些不能使用CGI或Servlet的HTML編寫者十分重要。但是,對于Servlet來說,直接設置Refresh頭更加方便。 注意Refresh的意義是"N秒之後刷新本頁面或訪問指定頁面",而不是"每隔N秒刷新本頁面或訪問指定頁面"。因此,連續刷新要求每次都發送一個Refresh頭,而發送204狀態代碼則可以阻止浏覽器繼續刷新,不管是使用Refresh頭還是<META HTTP-EQUIV="Refresh" ...>。 注意Refresh頭不屬于HTTP 1.1正式規範的一部分,而是一個擴展,但Netscape和IE都支持它。
User-Agent用戶代理的用戶代理字符串。
upgrade請求服務器升級到另一個協議。不能在HTTP/2中使用。
Via請通知服務器發送請求的代理服務器。
Warning實體可能會發生的問題的通用警告。
WWW-Authenticate客戶應該在Authorization頭中提供什麽類型的授權信息?在包含401(Unauthorized)狀態行的應答中這個頭是必需的。例如,response.setHeader("WWW-Authenticate", "BASIC realm=\"executives\"")。 注意Servlet一般不進行這方面的處理,而是讓Web服務器的專門機制來控制受密碼保護頁面的訪問(例如.htaccess)。
Server包含了處理請求的源頭服務器所用到的軟件相關信息。
Set-Cookie設置和頁面關聯的Cookie。Servlet不應使用response.setHeader("Set-Cookie", ...),而是應使用HttpServletResponse提供的專用方法addCookie。
Server服務器名字。Servlet一般不設置這個值,而是由Web服務器自己設置。

<br />
常用非標准頭

應答頭描述
Content-Security-Policy, X-Content-Security-Policy,X-WebKit-CSP定義內容安全策略
DNT (Do Not Track)0表示用戶願意目標站點追蹤用戶個人信息。1表示用戶不願意目標站點追蹤用戶個人信息。
X-ATT-DeviceId允許更簡單的解析用戶代理在AT&T設備上的MakeModel/Firmware
X-Csrf-Token,X-CSRFToken,X-XSRF-TOKEN防止跨站請求僞造
X-Content-Type-Options唯一的取值是"",阻止IE在響應中嗅探定義的內容格式以外的其他MIME格式
X-Forwarded-For一個事實標准,用來標識客戶端通過HTTP代理或者負載均衡器連接的web服務器的原始IP地址
X-Forwarded-Host一個事實標准,用來標識客戶端在HTTP請求頭中請求的原始host,因爲主機名或者反向代理的端口可能與處理請求的原始服務器不同
X-Forwarded-Proto一個事實標准,用來標識HTTP原始協議,因爲反向代理或者負載均衡器和web服務器可能使用http,但是請求到反向代理使用的是https
X-Http-Method-Override請求web應用時,使用header字段中給定的方法(通常是put或者delete)覆蓋請求中指定的方法(通常是post),如果用戶代理或者防火牆不支持直接使用put或者delete方法發送請求時,可以使用這個字段
X-Request-ID,X-Correlation-ID標識客戶端和服務端的HTTP請求
X-Requested-With標識Ajax請求,大部分js框架發送請求時都會設置它爲XMLHttpRequest
X-XSS-Protection過濾跨站腳本
X-UA-Compatible推薦首選的渲染引擎來展示內容,通常向後兼容,也用于激活IE中內嵌chrome框架插件
Upgrade-Insecure-Requests標識服務器是否可以處理HTTPS協議

狀態消息

狀態消息大體分五種:

分類分類描述
1**信息,服務器收到請求,需要請求者繼續執行操作
2**成功,操作被成功接收並處理
3**重定向,需要進一步的操作以完成請求
4**客戶端錯誤,請求包含語法錯誤或無法完成請求
5**服務器錯誤,服務器在處理請求的過程中發生了錯誤

常見的類型有以下:

狀態碼消息描述
200OK成功。請求的所有數據都在響應主體中。
301Moved Permanently所請求的頁面已經轉移至新的url。
302Found所請求的頁面已經臨時轉移至新的url。
304Not Modified未按預期修改文檔。客戶端有緩衝的文檔並發出了一個條件性的請求(一般是提供If-Modified-Since頭表示客戶只想比指定日期更新的文檔)。服務器告訴客戶,原來緩衝的文檔還可以繼續使用。
403Forbidden對被請求頁面的訪問被禁止。
404Not Found服務器無法找到被請求的頁面。
500Internal Server Error請求未完成。服務器遇到不可預知的情況。
502Bad Gateway請求未完成。服務器從上遊服務器收到一個無效的響應。
504Gateway Timeout網關超時。

(更多內容請自行查閱,本節到此爲止了.)

Http連接管理

短連接

HTTP 最早期的模型,也是 HTTP/1.0 的默認模型,是短連接。每一個 HTTP 請求都由它自己獨立的連接完成;這意味著發起每一個 HTTP 請求之前都會有一次 TCP 握手,而且是連續不斷的。
TCP 協議握手本身就是耗費時間的,所以 TCP 可以保持更多的熱連接來適應負載。短連接破壞了 TCP 具備的能力,新的冷連接降低了其性能。
這是HTTP/1.0的默認模型(如果沒有指定 Connection 協議頭,或者是值被設置爲 close)。而在 HTTP/1.1 中,只有當 Connection 被設置爲 close 時才會用到這個模型。

這個簡單的模型對性能有先天的限制:打開每一個 TCP 連接都是相當耗費資源的操作。客戶端和服務器端之間需要交換好些個消息。當請求發起時,網絡延遲和帶寬都會對性能造成影響。現代浏覽器往往要發起很多次請求(十幾個或者更多)才能拿到所需的完整信息,證明了這個早期模型的效率低下。

缺點:
1, 創建新連接耗費的時間;
2, TCP 連接的性能只有在該連接被使用一段時間後(熱連接)才能得到改善;

長連接

而HTTP/1.1(以及 HTTP/1.0 的各種增強版本)允許HTTP在請求結束之後將TCP連接保持打開狀態,以便爲未來的HTTP請求重用現存的連接。一個長連接會保持一段時間,重複用于發送一系列請求,節省了新建 TCP 連接握手的時間,還可以利用 TCP 的性能增強能力。當然這個連接也不會一直保留著:連接在空閑一段時間後會被關閉(服務器可以使用 Keep-Alive 協議頭來指定一個最小的連接保持時間)。

  • HTTP/1.0+ keep-alive
    客戶端可以通過包含 Connection: Keep-Alive首部請求將一條連接保持在打開狀態,如果服務器願意爲下一條請求將連接保持在打開狀態,就在響應中包含相同的首部。如果響應中沒有 Connection: Keep-Alive 首部, 客戶端就認爲服務器不支持 keep-alive, 會在發回響應報文之後關閉連接。
    1) timeout: Keep-Alive 響應首部發送的。 它代表服務器希望將連接保持在活躍狀態的時間。 但這並不是絕對;
    2) max: Keep-Alive 響應首部發送的。 它代表服務器還希望爲多少個事務保持此連接的活躍狀態。 但這並不是絕對;
    3) Keep-Alive 首部還可支持任意未經處理的屬性, 這些屬性主要用于診斷和調試。語法爲 name =value;

    例如Keep-Alive: max=5, timeout=3000, abc=123;

  HTTP/1.0 裏默認並不適用長連接。把 Connection 設置成 close 以外的其它參數都可以讓其保持長連接,通常會設置爲 retry-after。
  在 HTTP/1.1 裏,默認就是長連接的,協議頭都不用再去聲明它(但我們還是會把它加上,萬一某個時候因爲某種原因要退回到 HTTP/1.0 呢)。

  • HTTP/1.1 persistent
    現在HTTP/1.1 逐漸停止了對 keep-alive 連接的支持, 用一種名爲持久連接(persistent connection) 的改進型設計取代了它。
    與 HTTP/1.0+ 的 keep-alive 連接不同,HTTP/1.1 持久連接在默認情況下是激活的。 除非特別指明,否則 HTTP/1.1 假定所有連接都是持久的。要在事務處理結束之後將連接關閉,HTTP/1.1 應用程序必須向報文中顯式地添加一個Connection:close首部。這是與以前的 HTTP 協議版本很重要的區別,在以前的版本中,keep-alive 連接要麽是可選的,要麽根本就不支持.這種連接相當于是在HTTP/1.1之上默認開啓keep-alive

缺點:
1, 就算是在空閑狀態,它還是會消耗服務器資源;
2, 在重負載時,還有可能遭受 DoS attacks 攻擊;

流水線

默認情況下,HTTP 請求是按順序發出的。下一個請求只有在當前請求收到應答過後才會被發出。由于會受到網絡延遲和帶寬的限制,在下一個請求被發送到服務器之前,可能需要等待很長時間。

流水線是在同一條長連接上發出連續的請求,而不用等待應答返回。這樣可以避免連接延遲。理論上講,性能還會因爲兩個 HTTP 請求有可能被打包到一個 TCP 消息包中而得到提升。就算 HTTP 請求不斷的繼續,尺寸會增加,但設置 TCP 的 MSS(Maximum Segment Size) 選項,任然足夠包含一系列簡單的請求。

並不是所有類型的 HTTP 請求都能用到流水線:只有 idempotent 方式,比如 GET、HEAD、PUT 和 DELETE 能夠被安全的重試:如果有故障發生時,流水線的內容要能被輕易的重試。

今天,所有遵循 HTTP/1.1 的代理和服務器都應該支持流水線,雖然實際情況中還是有很多限制:一個很重要的原因是,任然沒有現代浏覽器去默認支持這個功能。

連接執行

一般項目需要進行大量請求場景,如果每個請求都進行串行執行會消耗大量的內存資源,引發自身的性能問題,但是如果每個請求都進行並行執行的話,會導致服務器在同一時間內處理大量請求,造成自身的效率問題.所以浏覽器一般都會把並行請求限制在一定數量內,一般大概五個左右吧(我大概估算,沒進行過驗證的).

連接分別示意圖
圖片描述
(還沒太懂也懶,直接MDN的拿來用的..)
(更多內容請自行查閱,本節到此爲止了.)

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复