這樣理解 HTTP,面試再也不用慌了

2021-10-09 08:31:04 字數 3766 閱讀 8383

目錄

2 post 和 get 的區別

3 常見狀態碼

4 http 首部

8 二進位制傳輸

9 多路復用

10 header 壓縮

11 服務端 push

12 quic

13 dns

14 從輸入 url 到頁面載入完成的過程

http 協議是個無狀態協議,不會儲存狀態。

先引入***和冪等的概念。

***指對伺服器上的資源做改變,搜尋是無***的,註冊是***的。

冪等指傳送 m 和 n 次請求(兩者不相同且都大於 1),伺服器上資源的狀態一致,比如註冊 10 個和 11 個帳號是不冪等的,對文章進行更改 10 次和 11 次是冪等的。

在規範的應用場景上說,get 多用於無***,冪等的場景,例如搜尋關鍵字。post 多用於***,不冪等的場景,例如註冊。

在技術上說:

2xx 成功

3xx 重定向

4xx 客戶端錯誤

5xx 伺服器錯誤

https 還是通過了 http 來傳輸資訊,但是資訊通過 tls 協議進行了加密。

tls 協議位於傳輸層之上,應用層之下。首次進行 tls 協議傳輸需要兩個 rtt ,接下來可以通過 session resumption 減少到乙個 rtt。

在 tls 中使用了兩種加密技術,分別為:對稱加密和非對稱加密。

對稱加密:

對稱加密就是兩邊擁有相同的秘鑰,兩邊都知道如何將密文加密解密。

非對稱加密:

有公鑰私鑰之分,公鑰所有人都可以知道,可以將資料用公鑰加密,但是將資料解密必須使用私鑰解密,私鑰只有分發公鑰的一方才知道。

tls 握手過程如下圖:

客戶端傳送乙個隨機值,需要的協議和加密方式

服務端收到客戶端的隨機值,自己也產生乙個隨機值,並根據客戶端需求的協議和加密方式來使用對應的方式,傳送自己的證書(如果需要驗證客戶端證書需要說明)

客戶端收到服務端的證書並驗證是否有效,驗證通過會再生成乙個隨機值,通過服務端證書的公鑰去加密這個隨機值並傳送給服務端,如果服務端需要驗證客戶端證書的話會附帶證書

服務端收到加密過的隨機值並使用私鑰解密獲得第三個隨機值,這時候兩端都擁有了三個隨機值,可以通過這三個隨機值按照之前約定的加密方式生成金鑰,接下來的通訊就可以通過該金鑰來加密解密

通過以上步驟可知,在 tls 握手階段,兩端使用非對稱加密的方式來通      信,但是因為非對稱加密損耗的效能比對稱加密大,所以在正式傳輸資料時,兩端使用對稱加密的方式通訊。

ps:以上說明的都是 tls 1.2 協議的握手情況,在 1.3 協議中,首次建立連線只需要乙個 rtt,後面恢復連線不需要 rtt 了。

http 2.0 相比於 http 1.x,可以說是大幅度提高了 web 的效能。

在 http 1.x 中,為了效能考慮,我們會引入雪碧圖、將小圖內聯、使用多個網域名稱等等的方式。這一切都是因為瀏覽器限制了同乙個網域名稱下的請求數量,當頁面中需要請求很多資源的時候,隊頭阻塞(head of line blocking)會導致在達到最大請求數量時,剩餘的資源需要等待其他資源請求完成後才能發起請求。

在 http 1.x 中,因為隊頭阻塞的原因,你會發現請求是這樣的

在 http 2.0 中,因為引入了多路復用,你會發現請求是這樣的

http 2.0 中所有加強效能的核心點在於此。在之前的 http 版本中,我們是通過文字的方式傳輸資料。在 http 2.0 中引入了新的編碼機制,所有傳輸的資料都會被分割,並採用二進位制格式編碼。

在 http 2.0 中,有兩個非常重要的概念,分別是幀(frame)和流(stream)。

幀代表著最小的資料單位,每個幀會標識出該幀屬於哪個流,流也就是多個幀組成的資料流。

多路復用,就是在乙個 tcp 連線中可以存在多條流。換句話說,也就是可以傳送多個請求,對端可以通過幀中的標識知道屬於哪個請求。通過這個技術,可以避免 http 舊版本中的隊頭阻塞問題,極大的提高傳輸效能。

在 http 1.x 中,我們使用文字的形式傳輸 header,在 header 攜帶 cookie 的情況下,可能每次都需要重複傳輸幾百到幾千的位元組。

在 http 2.0 中,使用了 hpack 壓縮格式對傳輸的 header 進行編碼,減少了 header 的大小。並在兩端維護了索引表,用於記錄出現過的 header ,後面在傳輸過程中就可以傳輸已經記錄過的 header 的鍵名,對端收到資料後就可以通過鍵名找到對應的值。

在 http 2.0 中,服務端可以在客戶端某個請求後,主動推送其他資源。

可以想象以下情況,某些資源客戶端是一定會請求的,這時就可以採取服務端 push 的技術,提前給客戶端推送必要的資源,這樣就可以相對減少一點延遲時間。當然在瀏覽器相容的情況下你也可以使用 prefetch 。

這是乙個谷歌出品的基於 udp 實現的同為傳輸層的協議,目標很遠大,希望替代 tcp 協議。

dns 的作用就是通過網域名稱查詢到具體的 ip。

因為 ip 存在數字和英文的組合(ipv6),很不利於人類記憶,所以就出現了網域名稱。你可以把網域名稱看成是某個 ip 的別名,dns 就是去查詢這個別名的真正名稱是什麼。

在 tcp 握手之前就已經進行了 dns 查詢,這個查詢是作業系統自己做的。當你在瀏覽器中訪問 www.google.com 時,會進行以下操作:

作業系統會首先在本地快取中查詢

沒有的話會去系統配置的 dns 伺服器中查詢

如果這時候還沒得話,會直接去 dns 根伺服器查詢,這一步查詢會找出負責 com 這個一級網域名稱的伺服器

然後去該伺服器查詢 google 這個二級網域名稱

接下來**網域名稱的查詢其實是我們配置的,你可以給 www 這個網域名稱配置乙個 ip,然後還可以給別的**網域名稱配置乙個 ip

以上介紹的是 dns 迭代查詢,還有種是遞迴查詢,區別就是前者是由客戶端去做請求,後者是由系統配置的 dns 伺服器做請求,得到結果後將資料返回給客戶端。

ps:dns 是基於 udp 做的查詢。

這是乙個很經典的面試題,在這題中可以將本文講的內容都串聯起來。

首先做 dns 查詢,如果這一步做了智慧型 dns 解析的話,會提供訪問速度最快的 ip 位址回來

接下來是 tcp 握手,應用層會下發資料給傳輸層,這裡 tcp 協議會指明兩端的埠號,然後下發給網路層。網路層中的 ip 協議會確定 ip 位址,並且指示了資料傳輸中如何跳轉路由器。然後包會再被封裝到資料鏈路層的資料幀結構中,最後就是物理層面的傳輸了

tcp 握手結束後會進行 tls 握手,然後就開始正式的傳輸資料

資料在進入服務端之前,可能還會先經過負責負載均衡的伺服器,它的作用就是將請求合理的分發到多台伺服器上,這時假設服務端會響應乙個 html 檔案

首先瀏覽器會判斷狀態碼是什麼,如果是 200 那就繼續解析,如果 400 或 500 的話就會報錯,如果 300 的話會進行重定向,這裡會有個重定向計數器,避免過多次的重定向,超過次數也會報錯

瀏覽器開始解析檔案,如果是 gzip 格式的話會先解壓一下,然後通過檔案的編碼格式知道該如何去解碼檔案

初始的 html 被完全載入和解析後會觸發 domcontentloaded 事件

cssom 樹和 dom 樹構建完成後會開始生成 render 樹,這一步就是確定頁面元素的布局、樣式等等諸多方面的東西

在生成 render 樹的過程中,瀏覽器就開始呼叫 gpu 繪製,合成圖層,將內容顯示在螢幕上了

這樣用糯公尺API,老闆再也不嘰歪!

apikey 3.糯公尺團單詳情介面 輸入交易id可以獲取團單的具體詳情資訊 5.糯公尺團單行政區域介面 輸入城市id可以獲取城市的商圈,行政區域資訊 7.根據團單id查詢相應的商戶 輸入團單id後去商戶的基本資訊和詳情 8.根據查詢條件獲取相應團單 輸入查詢條件可以獲取相應的團單資訊詳情 9.根據...

再也不能這樣活 再也不能那樣過

引言 再也不能這樣活 再也不能那樣過 生活就得前思後想 想好了你再做 略知一二起,從業三四年,專案五六個,加班七八點,讀書九十本,方向已茫然。這就是我這幾年it生涯的真實寫照,我想,也應該是部分同行的狀態。突然聽到劉歡大哥的 再也不能這樣活 再也不能那樣過 生活就得前思後想 想好了你再做 心裡突然有...

C語言 再也不寫排序演算法

在c語言乙個小專案裡面,大多數情況我們都是選擇自己造車輪,比如需要自己寫乙個排序演算法或者鍊錶,這樣的過程在學習的時候動手是充滿意義的,但是到了大專案之中,用標準庫和別人封裝好的演算法不香嗎?倘若蓋一棟樓之前,連每乙個磚塊都需要我們挖土燒磚,那麼這是多麼可怕巨大的工程量。所屬標準庫stdlib.h ...