前言

自從入職新公司到現在,我們前端團隊內部一直在做 ??每週一練 的知識複習計劃,我之前整理了一個 每週一練 之 數據結構與演算法 學習內容,大家也快去看看~~

最近三週,主要複習 網路基礎 相關的知識,今天我把這三週複習的知識和參考答案,整理成本文,歡迎各位朋友互相學習和指點,覺得本文不錯,也歡迎點贊哈????。

特別喜歡現在的每週學習和分享,哈哈哈~~??

??推薦一個 github 倉庫 —— 《awesome-http》,內容挺棒的。

註:本文整理資料來源網路,有些圖片/段落找不到原文出處,如有侵權,聯繫刪除。

一. 簡述瀏覽器輸入 URL 地址後發生的事情

1.1 描述

  1. 瀏覽器向 DNS 伺服器查找輸入 URL 對應的 IP 地址。
  2. NS 伺服器返回網站的 IP 地址。
  3. 瀏覽器根據 IP 地址與目標 web 伺服器在 80 埠上建立 TCP 連接。
  4. 瀏覽器獲取請求頁面的 HTML 代碼。
  5. 瀏覽器在顯示窗口內渲染 HTML 。
  6. 窗口關閉時,瀏覽器終止與伺服器的連接。

1.2 TCP 知識點補充

參考文章:《TCP三次握手和四次揮手協議》

建立 TCP 需要三次握手才能建立,而斷開連接則需要四次握手。整個過程如下圖所示:

TCP三次握手

所謂的三次握手,是指建立一個 TCP 連接時,需要客戶端和伺服器端總共發送三個包,三次握手的目的是連接伺服器的指定埠,建立 TCP 連接,並同步連接雙方的序列號和確認號並交換 TCP 窗口大小信息,在 SOCKET 編程中,客戶端執行 connect() 時,將會觸發三次握手:

TCP四次揮手:

TCP連接的拆除需要發送四個包,客戶端或者伺服器端均可主動發起揮手動作,在SOCKET編程中,任何一方執行close()即可產生揮手操作。

2. 請介紹常見的 HTTP 狀態碼(至少五個)

狀態碼是由 3 位數組成,第一個數字定義了響應的類別,且有五種可能取值:

1xx:指示信息–表示請求已接收,繼續處理。

  • 100 客戶必須繼續發出請求
  • 101 客戶要求伺服器根據請求轉換HTTP協議版本

2xx:成功–表示請求已被成功接收、理解、接受。

  • 200 (成功) 伺服器已成功處理了請求。 通常,這表示伺服器提供了請求的網頁。
  • 201 (已創建) 請求成功並且伺服器創建了新的資源。
  • 202 (已接受) 伺服器已接受請求,但尚未處理。

3xx:重定向–要完成請求必須進行更進一步的操作。

  • 300 (多種選擇) 針對請求,伺服器可執行多種操作。 伺服器可根據請求者 (user agent) 選擇一項操作,或提供操作列表供請求者選擇。
  • 301 (永久移動) 請求的網頁已永久移動到新位置。 伺服器返回此響應(對 GET 或 HEAD 請求的響應)時,會自動將請求者轉到新位置。
  • 302 (臨時移動) 伺服器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以後的請求。

4xx:客戶端錯誤–請求有語法錯誤或請求無法實現。

  • 400 (錯誤請求) 伺服器不理解請求的語法。
  • 401 (未授權) 請求要求身份驗證。 對於需要登錄的網頁,伺服器可能返回此響應。

  • 403 (禁止) 伺服器拒絕請求。

5xx:伺服器端錯誤–伺服器未能實現合法的請求。

  • 500 (伺服器內部錯誤) 伺服器遇到錯誤,無法完成請求。
  • 501 (尚未實施) 伺服器不具備完成請求的功能。 例如,伺服器無法識別請求方法時可能會返回此代碼。
  • 502 (錯誤網關) 伺服器作為網關或代理,從上游伺服器收到無效響應。
  • 503 (服務不可用) 伺服器目前無法使用(由於超載或停機維護)。 通常,這只是暫時狀態。
  • 504 (網關超時) 伺服器作為網關或代理,但是沒有及時從上游伺服器收到請求。
  • 505 (HTTP 版本不受支持) 伺服器不支持請求中所用的 HTTP 協議版本。

3. 請介紹常見的 HTTP 頭部(至少五個)

3.1 HTTP 頭部

更多完整內容,可以查看 《HTTP響應頭和請求頭信息對照表》

3.2 Request Header

參考文章:《HTTP常用頭部信息》

舉例:

3.3 Response Header

參考文章:《HTTP常用頭部信息》

舉例:

4. 請列舉常用的 HTTP 方法,並介紹 GET 與 POST 請求之間的區別

4.1 HTTP Request Method

參考文章:《HTTP請求方法對照表》

根據 HTTP 標準,HTTP 請求可以使用多種請求方法。 HTTP1.0 定義了三種請求方法: GET, POST 和 HEAD方法。 HTTP/1.1 新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

4.2 GET 與 POST 請求之間的區別

5. 請分別介紹 Cookie 和 Session 的作用及它們之間的區別

參考文章: 《3分鐘搞懂Cookie與Session》

5.1 Cookie簡單介紹

Cookie是存儲在用戶本地計算機上,用於保存一些用戶操作的歷史信息,當用戶再次訪問我們的伺服器的時候,瀏覽器通過HTTP協議,將他們本地的Cookie內容也發到咱們伺服器上,從而完成驗證。

  • Cookie 是存儲在瀏覽器客戶的一小片數據;
  • Cookie 可以同時被前臺與後臺操作;
  • Cookie 可以跨頁面存取;
  • Cookie 是不可以跨伺服器訪問的;
  • Cookie 有限制; 每個瀏覽器存儲的個數不能超過300個,每個伺服器不能超過20個,數據量不能超過4K;
  • Cookie 是有生命週期的,默認與瀏覽器相同,如果進程退出,cookie會被銷毀

5.2 Session

Session 存儲在我們的伺服器上,就是在我們的伺服器上保存用戶的操作信息。

當用戶訪問我們的網站時,我們的伺服器會成一個 Session ID,然後把 Session ID 存儲起來,再把這個 Session ID發給我們的用戶,用戶再次訪問我們的伺服器的時候,拿著這個 Session ID就能驗證了,當這個ID能與我們伺服器上存儲的ID對應起來時,我們就可以認為是自己人。

  • seesion 數據存儲在伺服器端;
  • 每一個會話分配一個單獨的 session_id;
  • session_id 通過 cookie 傳送到前臺,默認的 session_id 名稱是PHPSESSIONID;
  • 前臺只能看到 SessionID,而不能修改 Session 值;
  • 使用 Session之前需要先開啟會話;
  • Session存儲在 Session數組 $_SESSION;
  • Session存儲方式比較安全,但是如果 Session數量過多,會導致伺服器性能下降;

5.3 兩者區別

||Cookie|session| |---|---|---| |定義|瀏覽器保存用戶信息的文件,存儲的數量和字元數都有限制|伺服器把sessionID 和用戶信息、用戶操作,記錄在伺服器上,這些記錄就稱為session | |相同點|都是為了存儲用戶相關的信息| |存儲|客戶端|伺服器| |安全性|安全性不高,任何人都能直接查看|安全性高|

5.4 兩者結合使用

  • 存儲在服務端:通過 cookie存儲一個 session_id,然後具體的數據則是保存在 session中。如果用戶已經登錄,則伺服器會在 cookie中保存一個 session_id,下次再次請求的時候,會把該 session_id攜帶上來,伺服器根據 session_idsession庫中獲取用戶的 session數據。就能知道該用戶到底是誰,以及之前保存的一些狀態信息。這種專業術語叫做 server side session
  • session數據加密,然後存儲在 cookie中。這種專業術語叫做 client side session

6. 請介紹 HTTP 請求報文與響應報文格式

6.1 請求報文

請求報文由請求行請求頭部請求正文組成:

  • 請求行

格式為:

請求方法 + 空格 + URL + 空格 + 協議版本 + 回車符 + 換行符

例如:

GET www.baidu.com HTTP/1.1

常見的請求方法有:GET,HEAD,PUT,POST,TRACE,OPTIONS,DELETE以及擴展方法。

  • 請求頭部

格式為:

頭部欄位名 + 冒號(:) + 值 + 回車符 + 換行符

請求頭部為請求報文添加了一些附加信息,由「名/值」對組成,每行一對,名和值之間使用冒號分隔。

並且,在請求頭部的最後會有一個空行,表示請求頭部結束,這一行必不可少。

典型的請求頭部有:

|請求頭部|說明| |---|---| |Host|接受請求的伺服器地址,可以是IP:埠號,也可以是域名| |User-Agent|發送請求的應用程序名稱| |Connection|指定與連接相關的屬性,如Connection:Keep-Alive| |Accept-Charset|通知服務端可以發送的編碼格式| |Accept-Encoding|通知服務端可以發送的數據壓縮格式| |Accept-Language|通知服務端可以發送的語言|

  • 請求正文

一般使用在 POST 方法中, GET 方法不存在請求正文。

POST 方法適用於需要客戶填寫表單的場合。與請求數據相關的最常使用的請求頭是 Content-TypeContent-Length

6.2 響應報文

響應報文由狀態行響應頭部響應正文組成:

  • 狀態行

格式為:

協議版本 + 空格 + 狀態碼 + 空格 + 狀態碼描述 + 回車符 + 換行符

狀態碼劃分:

100?199的狀態碼是 HTTP / 1.1 向協議中引入了信息性狀態碼

200?299的狀態碼錶示成功; 300?399的狀態碼指資源重定向; 400?499的狀態碼指客戶端請求出錯; 500?599的狀態碼指服務端出錯

常見的狀態碼:

  • 響應頭部

格式為:

頭部欄位名 + 冒號(:) + 值 + 回車符 + 換行符

常見響應頭部:

7. HTTP/1.1 有什麼優缺點

參考文章:《HTTP/1.0 HTTP/1.1 HTTP/2.0 主要特性對比》

對於 HTTP/1.1,不僅繼承了 HTTP1.0簡單的特點,還克服了諸多 HTTP1.0性能上的問題。

7.1 HTTP/1.1 優點

  1. 增加持久性連接

也就是多個請求和響應可以利用同一個 TCP 連接,而不是每一次請求響應都要新建一個TCP連接,減少了建立和關閉連接的消耗和延遲。

Connection: keep-alive

  1. 增加管道機制

增加了管道機制,請求可以同時發出,但是響應必須按照請求發出的順序依次返回,性能在一定程度上得到了改善。

  1. 分塊傳輸

在 HTTP/1.1 版本中,可以不必等待數據完全處理完畢再返回,伺服器產生部分數據,那麼就發送部分數據,很明此種方式更加優秀一些,可以節省很多等待時間。

  1. 增加 host 欄位

使得一個伺服器能夠用來創建多個 Web 站點。

  1. 錯誤提示

HTTP/1.1 引入了一個 Warning 頭域,增加對錯誤或警告信息的描述,此外,在 HTTP/1.1 中新增了24個狀態響應碼(100,101,203,205,206,301,305… )。

  1. 帶寬優化

HTTP/1.1 中在請求消息中引入了 range頭域,它允許只請求資源的某個部分。

在響應消息中 Content-Range頭域聲明瞭返回的這部分對象的偏移值和長度。如果伺服器相應地返回了對象所請求範圍的內容,則響應碼為 206(Partial Content),它可以防止 Cache將響應誤以為是完整的一個對象,HTTP/1.1 加入了一個新的狀態碼 100(Continue)。客戶端事先發送一個只帶頭域的請求,如果伺服器因為許可權拒絕了請求,就回送響應碼 401(Unauthorized);如果伺服器接收此請求就回送響應碼 100,客戶端就可以繼續發送帶實體的完整請求了。

注意,HTTP/1.0 的客戶端不支持 100 響應碼。但可以讓客戶端在請求消息中加入 Expect頭域,並將它的值設置為 100-continue

7.2 HTTP/1.1 缺點

  1. 隊頭阻塞

此版本的網路延遲問題主要由於隊頭堵塞導致,雖然通過持久性連接得到改善,但是每一個請求的響應依然需要按照順序排隊,如果前面的響應處理較為耗費時間,那麼同樣非常耗費性能。

  1. 技術不成熟

還有此版本雖然引進了管道機制,但是當前存在諸多問題,且默認處於關閉狀態。

  1. 浪費資源

http/1.1 請求會攜帶大量冗餘的頭信息,浪費了很多寬頻資源。

8. 相比 HTTP/1.1,HTTP/2.0 有哪些新特性

參考文章:《HTTP1.0 HTTP/1.1 HTTP2.0 主要特性對比》

  • 二進位分幀

在應用層(HTTP/2.0)和傳輸層(TCP or UDP)之間增加一個二進位分幀層,從而突破 HTTP1.1 的性能限制,改進傳輸性能實現低延遲高吞吐量

可見,雖然 HTTP/2.0 的協議和 HTTP1.x 協議之間的規範完全不同了,但是實際上 HTTP/2.0並 沒有改變 HTTP1.x 的語義。

簡單來說,HTTP/2.0 只是把原來 HTTP1.x 的 headerbody 部分用 frame 重新封裝了一層而已。

  • 多路復用(連接共享)

允許同時通過單一的 HTTP/2 連接發起多重的請求-響應消息,這個強大的功能則是基於「二進位分幀」的特性。

從圖中可見,所有的 HTTP/2.0 通信都在一個 TCP 連接上完成,這個連接可以承載任意數量的雙向數據流。

每個數據流以消息的形式發送,而消息由一或多個幀組成。這些幀可以亂序發送,然後再根據每個幀頭部的流標識符(stream id)重新組裝。

  • 首部壓縮

HTTP1.1 不支持 header 數據的壓縮,HTTP/2.0 使用 HPACK 演算法對 header 的數據進行壓縮,這樣數據體積小了,在網路上傳輸就會更快。高效的壓縮演算法可以很大的壓縮 header ,減少發送包的數量從而降低延遲。

  • 伺服器推送

在 HTTP/2 中,伺服器可以對客戶端的一個請求發送多個響應,即伺服器可以額外的向客戶端推送資源,而無需客戶端明確的請求。

9. 請簡述 HTTPS 工作原理

9.1 HTTPS 簡介

參考文章:《深入淺出講解HTTPS工作原理》

HTTPS 並非是應用層的一種新協議。只是 HTTP 通信介面部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協議代替而已。

通常,HTTP 直接和 TCP 通信。當使用 SSL 時,則演變成先和 SSL 通信,再由 SSL 和 TCP 通信了。簡言之,所謂 HTTPS,其實就是身披 SSL 協議這層外殼的 HTTP。

在採用 SSL 後,HTTP 就擁有了 HTTPS 的加密、證書和完整性保護這些功能。也就是說HTTP 加上加密處理和認證以及完整性保護後即是 HTTPS。

HTTPS 協議的主要功能基本都依賴於 TLS/SSL 協議,TLS/SSL 的功能實現主要依賴於三類基本演算法:散列函數對稱加密非對稱加密,其利用非對稱加密實現身份認證和密鑰協商,對稱加密演算法採用協商的密鑰對數據加密,基於散列函數驗證信息的完整性。

9.2 HTTPS 工作原理

HTTPS 其實是有兩部分組成:HTTP + SSL / TLS,也就是在 HTTP 上又加了一層處理加密信息的模塊。服務端和客戶端的信息傳輸都會通過 TLS 進行加密,所以傳輸的數據都是加密後的數據

  1. 客戶端發起HTTPS請求

瀏覽器裡面輸入一個HTTPS網址,然後連接到服務端的443埠上。注意這個過程中客戶端會發送一個密文族給服務端,密文族是瀏覽器所支持的加密演算法的清單。

  1. 服務端配置

採用HTTPS協議的伺服器必須要有一套數字證書,可以自己製作,也可以向組織申請。區別就是自己頒發的證書需要客戶端驗證通過纔可以繼續訪問,而使用受信任的公司申請的證書則不會彈出提示頁面。

這套證書其實就是一對公鑰和私鑰,可以這麼理解,公鑰就是一把鎖頭,私鑰就是這把鎖的鑰匙,鎖頭可以給別人對某個東西進行加鎖,但是加鎖完畢之後,只有持有這把鎖的鑰匙纔可以解鎖看到加鎖的內容。

  1. 傳送證書

這個證書其實就是公鑰,只是包含了很多信息,如證書的頒發機構、過期時間等等。

  1. 客戶端解析證書

這部分工作是由客戶端的TLS來完成的,首先會驗證公鑰是否有效,如頒發機構、過期時間等等,如果發現異常則會彈出一個警告框,提示證書存在問題。如果證書沒有問題,那麼就生成一個隨機值,然後用證書對該隨機值進行加密。

注意一下上面提到的"發現異常"。證書中會包含數字簽名,該數字簽名是加密過的,是用頒發機構的私鑰對本證書的公鑰、名稱及其他信息做hash散列加密而生成的。客戶端瀏覽器會首先找到該證書的根證書頒發機構,如果有,則用該根證書的公鑰解密伺服器下發的證書,如果不能正常解密,則就是"發現異常",說明該證書是偽造的。

  1. 傳送加密信息

這部分傳送的是用證書加密後的隨機值,目的就是讓服務端得到這個隨機值,然後客戶端和服務端的通信就可以通過這個隨機值來進行加密和解密了。

  1. 服務端解密信息

服務端用私鑰解密後,得到了客戶端傳過來的隨機值,至此一個非對稱加密的過程結束,看到TLS利用非對稱加密實現了身份認證和密鑰協商。然後把內容通過該值進行對稱加密。

  1. 傳輸加密後的信息

這部分是服務端用隨機值加密後的信息,可以在客戶端被還原。

  1. 客戶端解密信息

客戶端用之前生成的隨機值解密服務端傳送過來的信息,於是獲取了解密後的內容,至此一個對稱加密的過程結束,看到對稱加密是用於對伺服器待傳送給客戶端的數據進行加密用的。整個過程即使第三方監聽了數據,也束手無策。

10. HTTP 和 HTTPS 的共同點和區別

  1. https 協議需要到 ca 申請證書,一般免費證書較少,因而需要一定費用。
  2. http 是超文本傳輸協議,信息是明文傳輸, https 則是具有安全性的ssl加密傳輸協議。
  3. http 和 https 使用的是完全不同的連接方式,用的埠也不一樣,前者是80,後者是443。
  4. http 的連接很簡單,是無狀態的; HTTPS 協議是由 SSL+HTTP 協議構建的可進行加密傳輸、身份認證的網路協議,比 http 協議安全。

11. 什麼是跨域,如何解決跨域

參考文章:《前端常見跨域解決方案(全)》

11.1 什麼是跨域

跨域,指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制。

  • 什麼是同源策略?

同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到 XSS 、 CSFR 等攻擊。所謂同源是指"協議+域名+埠"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。

  • 同源策略限制了以下行為:
  • CookieLocalStorageIndexDB 無法讀取
  • DOMJS對象無法獲取
  • Ajax請求發送不出去
  • 常見跨域場景:

所謂的同源是指:域名協議均為相同。

  • http://www.a.cn/index.html 調用 http://www.a.cn/server.php 非跨域。
  • http://www.a.cn/index.html 調用 http://www.b.cn/server.php 跨域,主域不同。
  • http://abc.a.cn/index.html 調用 http://def.b.cn/server.php 跨域,子域名不同。
  • http://www.a.cn:8080/index.html 調用 http://www.a.cn/server.php 跨域,埠不同。
  • https://www.a.cn/index.html 調用 http://www.a.cn/server.php 跨域,協議不同。
  • localhost 調用 127.0.0.1 跨域。

11.2 解決跨域

  1. jsonp 跨域
  2. document.domain + iframe 跨域
  3. window.name + iframe 跨域
  4. location.hash + iframe 跨域
  5. postMessage 跨域
  6. 跨域資源共享CORS
  7. withCredentials 屬性
  8. WebSocket 協議跨域
  9. node 代理跨域
  10. nginx 代理跨域

具體每一種解決方法,可以參考:《前端常見跨域解決方案(全)》

12. HTTP 中與緩存相關的頭部有哪些,它們有什麼區別

13. 分別介紹強緩存和協商緩存

瀏覽器緩存主要分為強緩存(也稱本地緩存)和協商緩存(也稱弱緩存)。

13.1 強緩存

強緩存是利用 http 頭中的 ExpiresCache-Control 兩個欄位來控制的,用來表示資源的緩存時間。

強緩存中,普通刷新會忽略它,但不會清除它,需要強制刷新。瀏覽器強制刷新,請求會帶上 Cache-Control:no-cachePragma:no-cache

通常,強緩存不會向伺服器發送請求,直接從緩存中讀取資源,在chrome控制檯的network選項中可以看到該請求返回200的狀態碼。分為 from disk cachefrom memory cache

  • from disk cache :一般非腳本會存在內存當中,如css,html等
  • from memory cache :資源在內存當中,一般腳本、字體、圖片會存在內存當

緩存命中緩存未命中狀態:

13.2 協商緩存

協商緩存就是由伺服器來確定緩存資源是否可用,所以客戶端與伺服器端要通過某種標識來進行通信,從而讓伺服器判斷請求資源是否可以緩存訪問。

普通刷新會啟用弱緩存,忽略強緩存。只有在地址欄或收藏夾輸入網址、通過鏈接引用資源等情況下,瀏覽器才會啟用強緩存,這也是為什麼有時候我們更新一張圖片、一個js文件,頁面內容依然是舊的,但是直接瀏覽器訪問那個圖片或文件,看到的內容卻是新的。

這個主要涉及到兩組 header 欄位: EtagIf-None-MatchLast-ModifiedIf-Modified-Since

向伺服器發送請求,伺服器會根據這個請求的request header的一些參數來判斷是否命中協商緩存。

緩存命中緩存未命中狀態:

13.3 流程

瀏覽器第一次發起請求,本地有緩存情況: 在瀏覽器第一次發起請求時,本地無緩存,向web伺服器發送請求,伺服器起端響應請求,瀏覽器端緩存。過程如下:

在第一次請求時,伺服器會將頁面最後修改時間通過 Last-Modified標識由伺服器發送給客戶端,客戶端記錄修改時間;伺服器還會生成一個Etag,並發送給客戶端。

瀏覽器後續再次進行請求時:

14. 請簡單介紹一下 LRU (Least recently used)演算法

參考文章:《LRU演算法》

14.1 原理

LRU(Least recently used,最近最少使用)演算法根據數據的歷史訪問記錄來進行淘汰數據,其核心思想是「如果數據最近被訪問過,那麼將來被訪問的幾率也更高」。

這裡有一張比較卡通的圖片:

14.2 實現

最常見的實現是使用一個鏈表保存緩存數據,詳細演算法實現如下:

  1. 新數據插入到鏈表頭部;
  2. 每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;
  3. 當鏈表滿的時候,將鏈表尾部的數據丟棄。

14.3 分析

  • 命中率

當存在熱點數據時,LRU的效率很好,但偶發性的、週期性的批量操作會導致LRU命中率急劇下降,緩存污染情況比較嚴重。

  • 複雜度

實現簡單。

  • 代價

命中時需要遍歷鏈表,找到命中的數據塊索引,然後需要將數據移到頭部。

結語

本文主要複習了 HTTP/HTTPS 的一些基礎知識,還有 HTTP 的其他版本的知識,對於面試也好,知識沉澱也好,這些也是我們作為開發者必須懂的。

作為一名前端開發者,說實話對 HTTP/HTTPS 瞭解還是太少,可能和平常工作內容有關。

關於我

本文首發在 pingan8787個人博客,如需轉載請保留個人介紹

微信公眾號


推薦閱讀:
相關文章