1. 前言
對於開發人員,無論前端還是後端,瞭解HTTP網路相關的知識,都是非常有必要的。本文希望以通俗易懂的文字,將HTTP這裡徹底搞定~
2. TCP/IP 協議族
一切的源點,都在於,計算機之間,也想要像人一樣,融入社會(網路),相互交流溝通(通訊)。而這一切,都是要基於互相有共同的語言,或者有彼此能夠理解的動作和行為。
比如,兩個人之間進行交流,那麼可以有以下幾種方式:
-
會說同一種語言,或會寫同一種文字。
-
做手勢,肢體語言、面部表情、點頭搖頭。
。。。
而所有的上述方式,都要基於雙方都能聽得懂or看的懂。我們可以把上述所有的方式,統稱為人溝通方式集合。
TCP/IP概念
計算機也是一樣的,如果兩個計算機之間要進行通訊,那麼它們之間也要有多種相互都理解的溝通方式,我們把計算機之間的所有通訊方式的集合,統稱為 TCP/IP ,也就是等同於 人溝通方式集合。所以,首先一定要理解的是,經常提到的 TCP/IP ,它只是一個集合的名字,和 TCP , IP 沒有關係啊!!!
協議
上面人的交流方式有好多種,那麼相對應計算機通訊的方式,也就有很多種,計算機通訊的方式,叫做協議。
需要注意的一點是,協議的功能不僅僅侷限於通訊,只要是在通訊的過程中,起到了一定的作用,的方法和工具,都是協議,舉例:
打電話,收發訊號的功能,是一種協議,查詢號碼歸屬地,也是一種協議,只要是參與打電話這個過程,都是一種協議。
總結:
- 計算機之間要想通訊,需要很多種協議相互配合,不是一兩個協議就能搞定的,每個協議各司其職,都有著獨一無二的作用。
- 協議之間是可以巢狀的,並不是說互相就沒有關係,比如ssh協議、http協議、ftp協議等都基於TCP協議,而dns協議、SMTP協議則屬於UDP協議。比如:我要去上海,TCP協議就是規定要走陸地的方式,UDP規定要走非陸地的方式,然後 ssh是坐火車,http是坐汽車,都屬於TCP陸地....dns是坐飛機,SMTP是坐船,都屬於UDP非陸地。。。
- 這麼多的協議,是分到不同的層上的,比如應用層上有ftp、http協議;網路層有IP協議。。。
- http協議,是針對 web伺服器、瀏覽器 之間通訊的,如果是其他服務之間通訊,那就可能是另一種協議了。這也能反映出,TCP協議是個大通用,其下可以針對不同的服務衍生出不同的協議,所以對於前端來說,主要研究的就是http協議。
計算機通訊的過程,是資訊從一個層到另一個層(節點到節點) 這樣傳遞,每個層(節點)上都有不同的協議(方式),不同的協議發揮著各自的作用,協議之間可能有包含的關係。
3. TCP/IP 分層
我們已經大概理解了層與協議的概念,之所以分不同的層,肯定是不同的層所實現的功能有很大的差異,即每個層都要完成一個大的獨立的功能,而層裡面會有多個協議去配合著實現功能。
前端一般掌握四層模型就可以了,感興趣的也可以瞭解一下細分成七層模型。
應用層
理解:連線了使用者與計算機各種應用程式,可以讓使用者完成各種想要做的事情。比如開啟qq,瀏覽器等等,這些軟體都是在應用層上。讓使用者能夠看的見、可操作,讓使用者能夠操作計算機。
裝置:該層的實際裝置,可以認為就是計算機本身
傳輸層
理解:在使用者計算機和目標計算機之間,提供可靠的、合理的資料傳輸服務。可以認為是溝通計算機和路由器之間的 橋樑,算是對外開放的一個視窗,提供 建立、維護、拆除 連線的功能,並且處理連線過程中的錯誤。
傳輸層的功能,就是建立“埠對埠”的通訊。相比之下,“網路層”的功能是建立“主機到主機”的通訊。只要確定了主機和埠,我們就能實現程式之間的交流。
裝置:該層沒有實際的裝置,可以認為是計算機裡面我們看不到的一個程式吧,專門負責對外的連線,公關。
網路層
理解:計算機之間的標識是 IP ,所以要想和對方通訊,就需要通過IP找到對方。而北京和上海之間,中間會有好多個裝置,所以怎麼通過一個IP,找到千里之外的對方,這就是網路層的任務。
裝置:路由器
資料鏈路層
理解:網路層是負責大範圍的查詢,比如快遞找到了你家小區;但是在小區裡具體幾號樓,則需要資料鏈路層。因為網路層查詢的IP都是公網IP,而區域網內的計算機都是私有IP,資料鏈路層能夠將計算機的私有IP和MAC地址對映起來,總之就是能找到小區裡你的家。除此之外,物理層走的是位元流,而鏈路層能將位元流封裝成幀,並且進行一些差錯檢測、流量控制等。
裝置:交換機
物理層
理解:物理層就是為各種物理裝置提供一個傳輸的通道,物理和物理裝置之間若要傳遞資訊,那麼就需要對一些特性描述進行定義,比如電壓、電流、插座尺寸等。該層流動的是位元流。
裝置:網線、水晶頭、光纜等
4. 資料包
傳送端在層與層之間傳輸資料時,每經過一層時必定會被打上一個該層所屬的首部資訊。反之,接收端在層與層傳輸資料時,每經過一層時會把對應的首部消去。這種把資料資訊包裝起來的做法稱為封裝。
乙太網首部
大概瞭解一下即可
(1)其中的源地址和目的地址是指網路卡的硬體地址(也叫MAC 地址),長度是48 位,是在網路卡出廠時固化的。
(2)注意網路卡晶片(例如DM9000A)收到的資料就是如上所示的一長串資料;其中包括乙太網幀頭、IP報報頭、傳輸層協議段頭、應用層所需資料。
(3)乙太網幀中的資料長度規定最小46 位元組,最大1500 位元組,ARP 和RARP 資料包的長度不夠46 位元組,要在後面補填充位。最大值1500 稱為乙太網的最大傳輸單元(MTU),不同的網路型別有不同的MTU,如果一個資料包從乙太網路由到撥號鏈路上,資料包度大於撥號鏈路的MTU了,則需要對資料包進行分片fragmentation)。ifconfig 命令的輸出中也有“MTU:1500”。注意,MTU 個概念指資料幀中有效載荷的最大長度,不包括幀首部的長度。
這裡只需要瞭解大概,在經過每一層,都要在資料包中新增上該層相關的資訊。
5. 與HTTP關係密切的協議:IP、TCP和DNS
從上面內容我們已經知道,資料會在 應用層 --> 傳輸層 --> 網路層 --> 資料鏈路層 這樣傳遞,而關於資料鏈路層的一些知識,感興趣的同學可以看一下阮一峰老師的文章。
我們只研究:
應用層:http協議、dns協議
傳輸層:TCP協議
網路層:IP協議
IP地址和MAC地址
每個計算機的網路卡都有一個全球唯一的地址來標識自己,不會重複。計算機和計算機之間傳送和傳輸資料都是通過網路卡進行的,所以計算機之間建立連線也就是兩個網路卡之間建立連線。網路卡的地址,就是資料包的傳送地址和接收地址,這叫做MAC地址。
理論上,單單依靠MAC地址,上海的網路卡就可以找到洛杉磯的網路卡了,技術上是可以實現的。但是, 面對著無數的計算機,如果都使用MAC地址進行通訊,那麼就需要維護一個極其龐大的MAC地址表,在查詢目的機器的時候,就需要向全世界傳送資料包,可想而知會造成多大的網路流量。
所以要將無數的計算機,劃分成一個一個的子網,每個子網都有個地址進行標識,這就是 IP 地址。
而關於 IP地址、子網掩碼、公網IP和區域網IP 等有關的知識,大家可以百度詳細的學一下。
這裡我們就還需知道,通訊的最後一定會根據 IP 地址找到對應的 MAC 地址,而幹這個的,就是 ARP 協議。
DNS
提供www域名到IP地址之間的解析服務。
而實際上,DNS伺服器查詢一個域名的IP,是需要多次迭代查詢的。
查詢crm.baidu.cn的IP的步驟:
- 客戶端首先向 根DNS伺服器 傳送 crm.baidu.cn 的請求。
- 根DNS伺服器 發現是cn,然後告訴你並返回 管理cn 的DNS伺服器 地址
- 接著客戶端去詢問 管理cn 的DNS伺服器 ,然後返回的是 baidu.cn 的地址。
- 此時,客戶端收到的,是百度公司的一個地址,傳送 crm.baidu.cn 給百度公司,返回給你 IP 。
即:(1) 得到 cn 的地址 (2) 得到 baidu.cn 的地址 (3) 得到 crm.baidu.cn 的地址
注意:瀏覽器會對網址的dns資訊進行快取,如果快取存在,則直接取得網址的IP
HTTP和TCP的區別
到這裡,很多同學還可能分不清HTTP和TCP,下面就先講一下區別
區別1: TCP是傳輸層,而http是應用層
區別2:
TCP就是單純的建立連線,不管傳的是啥資料,就比如打電話,只要雙方都接通了,TCP的任務就完成了,它不管雙方要說啥,用英文還是法語交流的。。。
而HTTP是定義了傳遞資料的格式和規範,像瀏覽器中見到的 header 中 Content-Type: text/html; ETag: "5c47ddbc-2b3" 。。。就像打電話過程中定義要用英語溝通一樣。
HTTP是基於TCP的,所以有HTTP一定有TCP,就像HTTP是要用英文打電話,那是不是得基於建立電話的連線。
總結:TPC/IP協議是傳輸層協議,主要解決資料如何在網路中傳輸,而HTTP是應用層協議,主要解決如何包裝資料。
把IP想像成一種高速公路,它允許其它協議在上面行駛並找到到其它電腦的出口。TCP和UDP是高速公路上的“卡車”,它們攜帶的貨物就是像HTTP,檔案傳輸協議FTP這樣的協議等。
HTTP是利用TCP在兩臺電腦(通常是Web伺服器和客戶端)之間傳輸資訊的協議。客戶端使用Web瀏覽器發起HTTP請求給Web伺服器,Web伺服器傳送被請求的資訊給客戶端。即TCP是個通用的協議,HTTP則是基於它在網頁web方面的傳輸方式。
6. TCP
到這裡,通過網路層和資料鏈路層,已經能夠實現了計算機找到另一個計算機了,但是真正的通訊,是計算機的程式之間交換資料,比如qq聊天。所以TCP/UDP所在的傳輸層,就是起到了計算機兩個程式間的通訊。
TCP,對方同意時才能建立連線,像打電話。
UDP,不管對方接受不,直接發過去,比如給對方發微信。
TCP概述
提供可靠的、安全的連線服務,具備以下功能:
- 將資料包進行分段傳輸,否則如果資料包特別大,那麼容易造成堵塞。
- 對每個分段後的資料包進行編號的控制順序,到達後再根據編號拼成完整的資料包。
- 資料傳輸過程中,對網路延遲、丟包等現象,有重發機制來保證資料的完整性。
- 控制流量,避免傳送速率過快,平穩的將資料傳輸過去。
- 使用“滑動視窗”的流量控制機制來高網路的吞吐量。
TCP首部
之前介紹過了,到達每一層都會封裝一個對應的首部,我們來看這層新增了什麼樣子的首部:
- 源埠和目的埠:存放著本機與目標計算機,各自的,本次連線所開通的,埠號。
- 序列號:連線傳輸時,傳輸的資料,每一個位元組都要進行順序的編號。例如,連線時的序號初始值是301,要傳輸的資料為100欄位,那麼再傳輸資料時,序號就從401開始。
- URG--緊急,當URG=1,表明緊急指標欄位有效。告訴系統此報文段中有緊急資料。
- ACK--確認,僅當ACK=1時,確認號欄位才有效。TCP規定,在連線建立後所有報文的傳輸都必須把ACK置1。
- RST--復位,當RST=1,表明TCP連線中出現嚴重差錯,必須釋放連線,然後再重新建立連線。
- 同步SYN,在連線建立時用來同步序號。當SYN=1,ACK=0,表明是連線請求報文,若同意連線,則響應報文中應該使SYN=1,ACK=1。
- 終止FIN,用來釋放連線。當FIN=1,表明此報文的傳送方的資料已經傳送完畢,並且要求釋放。
如上就是TCP首部的一些解釋,雙方計算機建立連線時的溝通,就是以如上的這些欄位進行交流,所以欄位的引數值,在連線過程中,也會根據實況進行改變。
TCP建立連線
三次握手
TCP建立兩個計算機的連線,就是用傳說中的三次握手,客戶端和服務端總共需要傳送3個包以確認連線的建立。
(1)第一次握手:Client將標誌位SYN置為1,隨機產生一個值seq=J,並將該資料包傳送給Server,Client進入SYN_SENT狀態,等待Server確認。
(2)第二次握手:Server收到資料包後由標誌位SYN=1知道Client請求建立連線,Server將標誌位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,並將該資料包傳送給Client以確認連線請求,Server進入SYN_RCVD狀態。
(3)第三次握手:Client收到確認後,檢查ack是否為J+1,ACK是否為1,如果正確則將標誌位ACK置為1,ack=K+1,並將該資料包傳送給Server,Server檢查ack是否為K+1,ACK是否為1,如果正確則連線建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間可以開始傳輸資料了。
四次揮手
TCP連線的釋放,就是傳說中的四次揮手。
(1)第一次揮手:Client傳送一個FIN,用來關閉Client到Server的資料傳送,Client進入FIN_WAIT_1狀態。
(2)第二次揮手:Server收到FIN後,傳送一個ACK給Client,確認序號為收到序號+1(與SYN相同,一個FIN佔用一個序號),Server進入CLOSE_WAIT狀態。
(3)第三次揮手:Server傳送一個FIN,用來關閉Server到Client的資料傳送,Server進入LAST_ACK狀態。
(4)第四次揮手:Client收到FIN後,Client進入TIME_WAIT狀態,接著傳送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手。
經典問題:
- 為什麼要三次握手,而不是兩次:
比如 A 向 B 傳送請求連線
第三次是需要A再確認一下,這次請求是不是還有效的,,,,設想如果網路延遲,A傳送的請求在5分鐘後才到達B(其實對於A來說這個請求已經失效了),這時需要A的第三次握手,來確認這個連線還有效不了。。。
- 釋放連線的時候,為什麼要四次揮手呢:
看圖中,第二次揮手, B 只是告訴A ,我收到了你關閉連線的請求了,但是資料還沒傳完呢,此時還可以繼續傳資料。。。然後當資料傳完了,B再向A傳送第三次揮手,告訴A資料傳完了,斷開連線吧。
- 四次揮手的最後,為什麼會有2ms的等待:
A向B傳送的第四次揮手,如果網路延遲,那麼B可能收不到,,,這時A有2ms的這個迴圈,繼續向B傳送。。。如果B收到了,那麼這2ms就消失了。
HTTP
前面介紹了這麼多,終於到了和前端息息相關的 HTTP 協議了,為什麼說和前端直接聯絡,因為 HTTP 協議,就是負責瀏覽器同伺服器後端進行通訊的規則,它允許將html文件等從web伺服器上,傳輸到使用者瀏覽器中。
HTTP協議定義了瀏覽器如何從Web伺服器請求Web頁面,以及伺服器如何把Web頁面傳送給客戶端。HTTP協議採用了請求/響應模型。客戶端向伺服器傳送一個請求報文,請求報文包含請求的方法、URL、協議版本、請求頭部和請求資料。伺服器以一個狀態行作為響應,響應的內容包括協議的版本、成功或者錯誤程式碼、伺服器資訊、響應頭部和響應資料。
HTTP 是基於 TCP 的,即 http 傳輸建立之前需要先建立tcp連線,也就是三次握手,在建立tcp連線之後方可真正請求響應請求。。
HTTP 請求/響應的步驟:
1、客戶端連線到Web伺服器
一個HTTP客戶端,通常是瀏覽器,與Web伺服器的HTTP埠(預設為80)建立一個TCP套接字連線。
2、傳送HTTP請求
通過TCP套接字,客戶端向Web伺服器傳送一個文字的請求報文,一個請求報文由請求行、請求頭部、空行和請求資料4部分組成。
3、伺服器接受請求並返回HTTP響應
Web伺服器解析請求,定位請求資源。伺服器將資源複本寫到TCP套接字,由客戶端讀取。一個響應由狀態行、響應頭部、空行和響應資料4部分組成。
4、釋放連線TCP連線
若connection 模式為close,則伺服器主動關閉TCP連線,客戶端被動關閉連線,釋放TCP連線;若connection 模式為keepalive,則該連線會保持一段時間,在該時間內可以繼續接收請求;
5、客戶端瀏覽器解析HTML內容
客戶端瀏覽器首先解析狀態行,檢視錶明請求是否成功的狀態程式碼。然後解析每一個響應頭,響應頭告知以下為若干位元組的HTML文件和文件的字符集。客戶端瀏覽器讀取響應資料HTML,根據HTML的語法對其進行格式化,並在瀏覽器視窗中顯示。
例如:在瀏覽器位址列鍵入URL,按下回車之後會經歷以下流程:
(1)、瀏覽器向 DNS 伺服器請求解析該 URL 中的域名所對應的 IP 地址;
(2)、解析出 IP 地址後,根據該 IP 地址和預設埠 80,和伺服器建立TCP連線;
(3)、瀏覽器發出讀取檔案(URL 中域名後面部分對應的檔案)的HTTP 請求,該請求報文作為 TCP 三次握手的第三個報文的資料傳送給伺服器;
(4)、伺服器對瀏覽器請求作出響應,並把對應的 html 文字傳送給瀏覽器;
(5)、釋放 TCP連線;
(6)、瀏覽器將該 html 文字並顯示內容;
HTTP 訊息結構
HTTP 請求方法
HTTP 首部欄位含義
- 通用首部欄位含義(前、後端通用,大概看一眼)
- 請求首部(request)
- 響應首部(response)
- 狀態碼
HTTP 2.0
- HTTP2.0的基本單位為二進位制幀流,而不是1.0的文字格式
- 訊息頭(報文首部)壓縮
- 多路複用,以前每次請求都需要建立TCP連線,經歷三次握手和四次揮手,,,2.0可以只建立一次連線,處理多個請求
- 服務端推送,伺服器會主動將資源推送給客戶端,例如把js和css檔案主動推送給客戶端而不用客戶端解析HTML後請求再響應。
HTTPS
由於HTTP協議過於簡單:
-
通訊使用明文(不加密),內容可能會被竊聽。
-
不驗證通訊方的身份,因此可能遭遇偽裝
-
無法驗證報文的完整性,所以有可能已遭篡改。
https是http的加密版本,是在http請求的基礎上,採用ssl進行加密傳輸。
要知道的是,HTTPS並非是應用層的一種新的協議。只是HTTP通訊介面部分用SSL或TLS協議代替而已。也就是說,所謂的HTTPS,其實就是身披SSL協議外殼的HTTP。
加密技術
對稱加密: 以DES為代表,客戶端和服務端拿到的金鑰是一樣的,即加密和解密使用的金鑰是一樣的,只有一個金鑰。
優點:演算法公開、計算量小、加密速度快、加密效率高。
缺點:祕鑰的管理和分發非常困難,不夠安全。在資料傳送前,傳送方和接收方必須商定好祕鑰,然後雙方都必須要儲存好祕鑰,如果一方的祕鑰被洩露,那麼加密資訊也就不安全了。另外,每對使用者每次使用對稱加密演算法時,都需要使用其他人不知道的唯一祕鑰,這會使得收、發雙方所擁有的鑰匙數量巨大,金鑰管理成為雙方的負擔。
非對稱加密: 以RES為代表,需要兩個金鑰來進行加密和解密,這兩個金鑰是配對的,分別是公開金鑰(公鑰)和私有金鑰(私鑰)。私鑰只能由一方安全保管,不能外洩,而公鑰則可以發給任何請求它的人。非對稱加密使用這對金鑰中的一個進行加密,而解密則需要另一個金鑰。
工作原理:
1.A向B傳送資訊,A和B都要產生一對用於加密和解密的公鑰和私鑰
2.A的私鑰保密,A的公鑰告訴B,B的私鑰保密,B的公鑰告訴A、
3.A要給B傳送資訊時,A用B的公鑰加密資訊,因為A知道B 的公鑰
4.A將這個訊息發給B,(已經用B的公鑰加密訊息)
5.B收到這個訊息後,B用自己的私鑰解密A的訊息,其他所有收到這個報文的人都無法解密,因為只有B才有B 的私鑰。
優點:安全性更高,公鑰是公開的,祕鑰是自己儲存的,不需要將私鑰給別人。
缺點:加密和解密花費時間長、速度慢,只適合對少量資料進行加密。
HTTPS採用共享金鑰加密和公開金鑰加密兩者並用的混合加密機制。在交換金鑰環節使用非對稱金鑰加密方式,之後建立的通訊交換報文階段則使用對稱金鑰加密方式。
確認加密演算法的過程使用的是非對稱性加密。資料傳輸過程使用對稱性加密。
輸入url後發生了什麼
1. 瀏覽器位址列輸入 URL 並回車
2. 瀏覽器查詢當前URL是否存在快取,快取是否過期(URL對應的IP)
3. DNS 解析 URL 對應的IP(如果第2步沒快取的情況下)。這裡涉及到了DNS迭代查詢
,回看文中關於 DNS 那部分。
4. 根據 IP 建立 TCP 的連線(三次握手)
5. HTTP 發起請求
6. 伺服器處理請求,瀏覽器接收 HTTP 響應
7. 渲染頁面,構建 DOM 樹
8. 關閉 TCP 連線(四次揮手)
複製程式碼
最後:字寫了很多,現在有點迷糊,以後再慢慢完善~