本篇要研究的內容為前端的開發。我們知道儲存於伺服器端的統稱為後端技術,而前端技術是指透過瀏覽器到使用者端計算機的統稱。因此,前端的所有知識都和“瀏覽器”緊密相關,在本篇文章中,我們將透過介紹瀏覽器的誕生原因及發展歷史來詳細地闡述瀏覽器的本質。
軟體開發架構
C/S,B/S架構
隨著網際網路的推廣和普及,誕生了很多基於網路的軟體,其中就有我們在這一章中索要介紹的C/S,B/S架構。
C/S架構,即客戶機Client(C)/伺服器Server(S)架構,顧名思義,當使用者想正常使用C/S架構軟體時必須下載一個客戶端(主要用來傳送資料),且在遠端有一個服務端與之響應。可是,當使用者使用的程式越來越多,一個新的問題也隨之一併誕生,比如使用者想使用20個軟體,他就必須下載20個客戶端。
於是,就有人提出,有沒有可能設計出一種“超級客戶端”,使用者只要下載這個“超級客戶端,就可以給多個相容的服務端傳送請求。這個“超級客戶端”就是我們現在耳熟能詳的“瀏覽器“,而對應的瀏覽器Browser和伺服器 Server的架構也就被我們稱為B/S架構。
提醒:B/S架構其實是一種特殊的C/S架構。
瀏覽器發展史
瀏覽器的誕生原因可以追溯到網際網路的發展。以下是瀏覽器的發展歷史:
- 早期:在網際網路誕生初期,人們需要一種方式來訪問網頁內容。最早的瀏覽器是由蒂姆·伯納斯-李(Tim Berners-Lee)開發的WorldWideWeb(後來改名為Nexus)瀏覽器,它是第一個可以瀏覽網頁的圖形化介面。
- 1990年代初期:隨著網際網路的普及,出現了一些較為流行的瀏覽器,如NCSA Mosaic和Netscape Navigator。Netscape Navigator在當時的市場份額中佔據主導地位。
- 1990年代中期:微軟推出了Internet Explorer,並將其捆綁在Windows作業系統中。這導致了一場著名的“瀏覽器大戰”,最終Internet Explorer取得了主導地位。
- 2000年代初期:Mozilla基金會推出了Mozilla Firefox瀏覽器,它的開源性質和創新功能吸引了許多使用者。同時,Google也推出了Chrome瀏覽器,憑藉其速度和簡潔的介面逐漸蠶食市場份額。
- 移動瀏覽器:隨著智慧手機的普及,移動瀏覽器變得越來越重要。Safari成為iOS裝置的預設瀏覽器,而Android裝置則通常使用Chrome瀏覽器。
- HTML5和現代瀏覽器:HTML5的出現推動了瀏覽器的發展,現代瀏覽器支援更多的功能和互動性,如影片播放、地理定位、WebGL等。
- 瀏覽器的多樣化:除了主流瀏覽器外,還出現了許多其他瀏覽器,如Opera、Safari、Edge等,使用者可以根據自己的喜好和需求選擇合適的瀏覽器。
總的來說,瀏覽器的發展歷史是一個競爭激烈的過程,不斷湧現出新的技術和功能,以滿足使用者對於更快速、更安全、更便捷網路瀏覽體驗的需求。
瀏覽器的本質
正如前文提到的,瀏覽器其實就是一個“超級客戶端“,它會將請求的資料傳送到不同的客戶端,並將伺服器返回的前端頁面透過一定的操作渲染到本地,所以我們可以說瀏覽器的本質其實就是一種直譯器。
從輸入一個網址到瀏覽器顯示頁面的全過程
瀏覽器輸入一個地址到看到頁面資訊的過程可以分為以下幾個步驟:
-
在瀏覽器中輸入網址(URL): 使用者在瀏覽器的位址列中輸入目標網址(例如:https://www.example.com),並按下Enter鍵。
-
DNS解析:瀏覽器首先會將輸入的網址傳送給DNS伺服器,DNS伺服器會將域名解析為對應的IP地址。這個過程涉及到遞迴查詢和迭代查詢,最終得到目標伺服器的IP地址。
-
建立TCP連線:瀏覽器使用HTTP協議與目標伺服器建立TCP連線。TCP是一種可靠的傳輸協議,透過三次握手建立連線,確保資料的可靠傳輸。
-
傳送HTTP請求:建立TCP連線後,瀏覽器會向目標伺服器傳送HTTP請求。請求中包含了請求方法(GET、POST等)、請求頭(包含瀏覽器資訊、Cookie等)和請求體(POST請求時攜帶的資料)。
-
伺服器處理請求:目標伺服器接收到瀏覽器傳送的HTTP請求後,會根據請求的內容進行處理。處理的過程可能包括讀取資料庫、執行後臺邏輯等。
-
返回HTTP響應:伺服器處理完請求後,會生成HTTP響應併傳送給瀏覽器。響應中包含了狀態碼、響應頭(包含伺服器資訊、Cookie等)和響應體(包含HTML、CSS、JavaScript等頁面內容)。
-
瀏覽器渲染頁面:瀏覽器接收到HTTP響應後,會解析響應內容,並根據HTML、CSS、JavaScript等資源渲染頁面。渲染過程包括解析HTML結構、載入和解析CSS樣式、執行JavaScript程式碼等。
-
頁面顯示:瀏覽器將渲染後的頁面顯示給使用者,使用者可以看到頁面上的內容。
-
斷開TCP連線: 頁面渲染完成後,如果沒有keep-alive機制或者WebSocket等長連線技術,瀏覽器會傳送一個關閉TCP連線的請求給伺服器,進而兩者斷開連線。
1、在瀏覽器中輸入網址(URL)
當在瀏覽器中輸入網址時,瀏覽器其實就已在智慧匹配 url 了,他會從歷史記錄,書籤等地方,找到已經輸入的字串可能對應的 url,然後給出智慧提示,讓你可以補全url地址。
對於 google的chrome 的瀏覽器,他甚至會直接從快取中把網頁展示出來,就是說,你還沒有按下 enter,頁面就出來了。
(1)簡析URL的組成
- URL 的元素組成也和上述大致相似
- 其中 訪問協議 和 域名是必須的,目錄名和檔名可以忽略
- 相應的 URL 請求對應在伺服器上的檔案路徑如下
(2)分析域名是否規範
-
首先,瀏覽器做的第一步就是會解析URL得到裡面的引數,分析域名是否規範,並將域名和需要的請求的資源分離開來,從而瞭解需要請求的是哪個伺服器,請求的是伺服器上的什麼資源等等。
-
瀏覽器對URL進行解析之後,瀏覽器確定了目標伺服器和檔名,接下來就是需要根據這些訊息封裝成一個HTTP請求報文傳送出去。
-
HTTP請求報文的例子為:
2、DNS解析
在解析過程之前我們先理解幾個概念。
(1)DNS是什麼?
DNS(Domain Name System)是一種用於將域名解析為IP地址的系統。(把我們的域名對映為IP地址,這就是DNS的作用)
它可以將人們易於記憶的域名轉換為伺服器可識別的IP地址,這樣使用者就可以使用域名訪問網站,而不必直接輸入數字格式的IP地址。
在瀏覽器中輸入網址時,電腦會先向DNS伺服器傳送請求,獲取該網址對應的IP地址,並在成功獲取後直接連線該IP地址對應的伺服器,在伺服器端獲取網頁內容並顯示出來,完成整個訪問過程。因此,DNS在網際網路中起著至關重要的作用。
(2)IP和域名的關係
IP(Internet Protocol)地址是一個數字標識,用於唯一識別連線到網際網路上的每個計算機、伺服器和其他裝置。域名則是網站的人類可讀的名稱。域名系統(DNS伺服器)可以將域名轉換為與之關聯的IP地址。
簡單來說,IP地址是網路裝置的識別符號,而域名則是方便人們記憶和使用的網路地址別名。
域名系統透過將 域名 對映到 IP地址,使網際網路上的使用者能夠以易記的方式訪問特定的網站或伺服器。
(3)域名伺服器概念圖
從上面這張圖可以看到,域名的管理是分層次的。最高階是根,也叫做根伺服器。從上往下功能逐漸細化。DNS就是和這些伺服器進行打交道。
(4)DNS域名解析IP地址的過程
請求一旦發起,瀏覽器首先要做的事情就是解析這個域名。
1、一般來說,瀏覽器會首先檢視本地硬碟的 hosts 檔案,看看其中有沒有和這個域名對應的規則,如果有的話就直接使用 hosts 檔案裡面的 ip 地址。
2、如果在本地的 hosts 檔案沒有能夠找到對應的 ip 地址,瀏覽器會發出一個 DNS請求到本地DNS伺服器 。本地DNS伺服器一般都是你的網路接入伺服器商提供,比如中國電信,中國移動。
3、查詢你輸入的網址的DNS請求到達本地DNS伺服器之後,本地DNS伺服器會首先查詢它的快取記錄,如果快取中有此條記錄,就可以直接返回結果,此過程是遞迴的方式進行查詢。如果沒有,本地DNS伺服器還要向DNS根伺服器進行查詢。
4、根DNS伺服器沒有記錄具體的域名和IP地址的對應關係,而是告訴本地DNS伺服器,你可以到域伺服器上去繼續查詢,並給出域伺服器的地址。這種過程是迭代的過程。
5、本地DNS伺服器繼續向域伺服器發出請求,在這個例子中,請求的物件是.com域伺服器。.com域伺服器收到請求之後,也不會直接返回域名和IP地址的對應關係,而是告訴本地DNS伺服器,你的域名的解析伺服器的地址。
6、最後,本地DNS伺服器向域名的解析伺服器發出請求,這時就能收到一個域名和IP地址對應關係,本地DNS伺服器不僅要把IP地址返回給使用者電腦,還要把這個對應關係儲存在快取中,以備下次別的使用者查詢時,可以直接返回結果,加快網路訪問。
(5)DNS解析時發現域名和IP不一致,訪問了該域名會如何?
域名和IP不一致,域名解析成了其他的的IP地址,但是這個IP地址正確。訪問該域名就會訪問其他的網站。
知乎上有一個阿里巴巴的回答:
從技術上來講是可以解析到任意IP地址的,這時候針對這個地址發起HTTP訪問,HTTP頭中的host欄位會是你的域名(而非該IP對應站點的域名),如果對方的網站HTTP伺服器沒有做對應的防護就可以訪問,如果對方的網站HTTP伺服器有防護則無法訪問。
域名和IP不一致,域名解析成了其他的的IP地址,但是這個IP地址錯誤,訪問該域名就會失敗。
可參考:DNS解析時發現域名和IP不一致,訪問了該域名會如何(大廠真題)
補充:
- 客戶端在DNS請求報文中申請使用的是遞迴查詢(也就是RD欄位置1了),但在所配置的本地名稱伺服器上是禁用遞迴查詢(DNS伺服器一般預設支援遞迴查詢的),即在應答DNS報文頭部的RA欄位置0。
- 其中,DNS 使用的是 UDP 協議,也就是說上面各種請求的轉發,都是基於 UDP 這個無連線協議的。
3、瀏覽器與伺服器建立TCP連線(80埠,三次握手)
在HTTP工作開始之前,web瀏覽器首先要透過網路與web伺服器建立連線,該連線是透過TCP來完成的。
PS:為什麼要先建立TCP呢?
因為HTTP是比TCP更高層次的應用層協議,根據規則,只有低層協議建立之後才能進行更高層次協議的連線,因此要先建立TCP連線,一般TCP連線的埠號是80。
三次握手的流程:
-
第一次握手:客戶端傳送syn包(syn=j)到伺服器,並進入SYN_SEND狀態,等待伺服器確認;
-
第二次握手:伺服器收到syn包,必須確認客戶的SYN(ack=j+1),同時自己也傳送一個SYN包(syn=k),即SYN+ACK包,此時伺服器進入SYN_RECV狀態;
-
第三次握手:客戶端收到伺服器的SYN+ACK包,向伺服器傳送確認包ACK(ack=k+1),此包傳送完畢,客戶端和伺服器進入ESTABLISHED狀態,完成三次握手。
具體的TCP連線的三次握手和斷開的四次揮手 參照站內文章:網路程式設計之TCP協議的三次握手和四次揮手 - Xiao0101 - 部落格園 (cnblogs.com)
4、瀏覽器傳送HTTP請求文件
建立了TCP連線之後,web瀏覽器就會向web伺服器發起一個http請求。
一個典型的 http request header 一般需要包括請求的方法,例如 GET 或者 POST 等,不常用的還有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,一般的瀏覽器只能發起 GET 或者 POST 請求。
(1)HTTP請求報文都有什麼組成?
HTTP請求報文主要由三個部分組成:請求行、請求頭和請求體。具體如下:
請求行:包含請求方法、URI(請求的資源路徑)和HTTP協議版本。例如:GET /index.html HTTP/1.1。
- 常見的方法為:GET、POST、PUT、DELETE等
- 常見的版本為:HTTP1.0、HTTP1.1、HTTP2.0等
請求頭(Header): 包含了客戶端向伺服器傳送的附加資訊,例如瀏覽器型別、字元編碼、認證資訊等。請求頭以鍵值對的形式存在,多個鍵值對之間以換行符分隔。例如:
Accept:image/gif.image/jpeg.*/*
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
請求體(Body): 存放請求引數,即瀏覽器向伺服器傳輸資料的實體部分。常用於POST方法提交請求時,傳送表單資料、JSON資料等型別的資料。
需要注意的是,並不是所有的HTTP請求都必須帶有請求體,像GET請求通常不需要傳送請求體。
為什麼 HTTP 報文中要存在 “空行”?
因為 HTTP 協議並沒有規定報頭部分的鍵值對有多少個。空行就相當於是 “報頭的結束標記”, 或者是 “報頭和正文之間的分隔符”。
HTTP 在傳輸層依賴 TCP 協議, TCP 是面向位元組流的. 如果沒有這個空行, 就會出現 “粘包問題”。
5、伺服器處理請求
-
目標伺服器接收到瀏覽器傳送的HTTP請求後,會根據請求的內容進行相應的處理。
-
這個過程會涉及到後端服務的執行,例如使用Nginx作為反向代理伺服器將請求轉發給後端Web框架(如Django、Flask等)。
6、伺服器傳送HTTP響應
- 瀏覽器的 HTTP 請求報文透過 TCP 三次握手建立的連線通道被切分成若干報文段分別傳送給伺服器,伺服器在收到這些報文段後,按照序號以原來的順序重組 HTTP 請求報文。
- 然後處理並返回一個 HTTP 響應。
- 當然,HTTP 響應報文也要經過和 HTTP 請求報文一樣的過程。
- HTTP的響應報文:response響應報文,即從Web伺服器到客戶機(瀏覽器)的應答。報文的所有欄位都是ASCII碼。
-
HTTP 響應報文由狀態行、響應頭部、空行 和 響應包體 4 個部分組成
-
reposes裡面的狀態碼:重要
-
狀態行:狀態碼(列舉常見的)
-
200 : 響應成功
301:永久重定向,請求資源的url已永久更改,在響應中給出了新的url。 -
302:臨時重定向。
-
304:not modify(未改變,和快取裡面的是一樣的)
-
404:not found ,網頁不存在。
-
502:bad gateway (閘道器故障),但是後端的real server掛了。
-
500:內部伺服器錯誤。(伺服器崩潰了)
-
-
響應頭部:響應欄位:
-
Date:日期,通用欄位,但通常出現在響應頭裡,表示 HTTP 報文建立的時間,客戶端可以使用這個時間再搭配其他欄位決定快取策略
-
Server:Server 響應報頭域包含了伺服器用來處理請求的軟體資訊及其版本。它和 User-Agent 請求報頭域是相對應的,前者傳送伺服器端軟體的資訊,後者傳送客戶端軟體(瀏覽器)和作業系統的資訊。
-
cache-control: max-age=30
-
content-type:傳遞過來的型別。
7、瀏覽器渲染頁面
- 瀏覽器接收到伺服器返回的資料包,根據瀏覽器的渲染機制對相應的資料進行渲染。
- 渲染就是將響應報文裡的html檔案+圖片+影片等展示出來,看到效果。
- 瀏覽器支援HTML語言,支援http,播放器等功能。
8、釋放TCP連線(四次揮手)
- 瀏覽器和伺服器都不再需要傳送資料後,四次揮手斷開 TCP 連線。
四次握手指斷開TCP協議連線時客戶端和伺服器之間的互動過程
- 客戶端向伺服器傳送一個FIN(結束)報文
- 表示要關閉連線。
- 伺服器收到FIN報文後向客戶端回送一個ACK報文
- 表示已經收到客戶端的請求。
- 如果伺服器還有資料需要傳送給客戶端
- 則繼續傳送直到資料全部傳送完畢。
- 伺服器傳送一個FIN報文,表示資料已經全部傳送完畢
- 可以關閉連線。
- 客戶端收到FIN報文後向伺服器傳送一個ACK報文,表示確認收到關閉請求。
- 此時客戶端需要進入TIME-WAIT狀態,等待兩倍的報文最大生存時間,以保證資料已經被全部傳輸完畢。
- 如果伺服器沒有收到來自客戶端的ACK報文,則會重傳FIN報文。