已發布到 程式員小灰 公號
前言
有人說,如果你懂得瀏覽器的作業原理,你就能解決80%的前端難題,
是的,了解瀏覽器的作業原理,有助于你的作業;而了解TCP/IP 、HTTP等網路協議,更是對你未來的職業發展大有裨益,
下面,我總結了4個面試常考的關于瀏覽器和網路通信的問題,為你重新梳理瀏覽器,網路通信、頁面渲染、JavaScript、瀏覽器安全等知識,從而讓你對整個前端后端體系有全新的認識,
第一問:Chrome為什么打開一個頁面,會有4個行程?
學習掌握:瀏覽器中的網路流程,頁面渲染程序,JavaScript執行流程,以及Web安全理論,下面展開問題了解多行程架構:
多行程架構的學習
行程和執行緒的概念混淆
如計算來說,單執行緒就是一個接一個的計算,多執行緒就是同時處理多個計算,多執行緒是指程式中包含多個執行流,即在一個程式中可以同時運行多個不同的執行緒來執行不同的任務,就是說允許單個程式創建多個并行執行,
單執行緒是程式中的一個執行流,每個執行緒都有自己的專有暫存器(堆疊指標、程式計數器等),但代碼區是共享的,即不同的執行緒可以執行同樣的函式,
多執行緒也是程式,所以執行緒需要占用記憶體,執行緒越多占用記憶體也越多,多執行緒需要協調和管理,所以需要CPU時間跟蹤執行緒;執行緒之間對共享資源的訪問會相互影響,必須解決競用共享資源的問題;執行緒太多會導致控制太復雜,
單執行緒在程式執行時,所走的程式都是按照連續順序下來的,前面的必須處理好,才會執行后面的,多執行緒運行就是一個行程內有多個相對獨立的并且實作特定的任務以競爭CPU的方式執行,宏觀上是并發,實際上是分時執行,只是執行的時間片較短,
每個正在運行的程式即是行程,至少包含一個執行緒,這個執行緒叫主執行緒,它在程式啟動時被創建,用于執行main函式,只有一個主執行緒的程式,稱為單執行緒程式,擁有多個執行緒的程式,稱為多執行緒程式,
行程是當一個程式開始運行時,它就是一個行程,行程包括運行中的程式和程式所使用到的記憶體和系統資源(一個行程又是由多個執行緒所組成的)
多執行緒的好處就是可以提高CPU的利用率,在多執行緒程式中,如果一個執行緒必須等待的時候,CPU可以運行其它的執行緒而不是等待,這樣可以大大地提高程式的效率,
所以,執行緒是不能單獨存在的,它是由行程來啟動和管理的,一個行程就是一個程式的運行實體,執行緒是依附于行程的,而行程中使用多執行緒并行處理能提升運算效率,執行緒之間共享行程中的資料,當一個行程關閉后,作業系統會回收行程所占用的記憶體,
目前的多行程架構瀏覽器Chrome包括,1個瀏覽器主行程,1個GPU行程,1個網路行程,多個渲染行程和多個插件行程,
so,打開一個頁面,為啥有4個行程?因為打開1個頁面:至少需要1個網路行程,1個瀏覽器行程,1個GPU行程以及1個渲染行程,
雖然多行程模型提升了瀏覽器的穩定性、流暢性和安全性,但是帶來了更高的資源占用,更復雜的體系架構,so,Chrome官方要構建一個更內聚,松耦合,易于維護和擴展的系統,
第二問:TCP協議是如何保證頁面檔案能被完整送達瀏覽器的?
對于在網路中,我們知道一個檔案通常會被拆分為很多資料包來進行傳輸,而資料包在傳輸程序中又有很大的可能會丟失或者出錯,保證頁面檔案完整地送達瀏覽器是有必要的,
下面就這三方面展開描述:
- 資料包如何送達到主機
- 主機如何將資料包轉交給應用
- 資料是如何被完整地送達到應用程式
資料包從主機A送到主機B,資料包上會附加上主機B的IP地址資訊,主機A本身的IP地址,這些附加的資訊會被裝進一個IP頭的資料結構里(包含IP版本,源IP地址,目標IP地址,生存時間等)
這些一般我們都了解,下面主要說明TCP(Transmission Control Protocol),傳輸控制協議是一種面向連接的,可靠的,基于位元組流的傳輸層通信協議,在簡化的計算機網路OSI模型中,它完成第四層傳輸層所指定的功能,
用戶資料報協議(UDP)是同一層內另一個重要的傳輸協議,
在因特網協議族中,TCP層是位于IP層之上的,TCP->IP,應用層之下的中間層,應用層->中間層,不同主機的應用層之間經常需要可靠的,像管道一樣的連接,但是IP層不提供這樣的流機制,而是提供不可靠的包進行交換,
TCP為了保證不發生丟包的情況,就給每個包一個序號,同時序號也保證了傳送到接收端物體的包的按序接收,接收端物體對已成功收到的包發回一個相應的確認資訊(ACK),如果發送端物體在合理的往返時延(RTT)內未收到確認,那么對應的資料包就被假設為已丟失并進行重傳,
- 資料在
TCP層稱為流 - 資料分組稱為分段
TCP協議的運作:連接創建,資料傳送,連接終止,
那你了解什么是TCP嗎?這一點大部分人應該只會說它是一種協議,
TCP傳輸控制協議是TCP/IP,傳輸控制協議Internet協議中的主要協議之一,TCP/IP是一套通信協議,用于連接Internet以及大多數其他計算機網路上的主機,
協議是一種共同商定的用于執行某件事的格式,對于計算機,最常用于指一組規則,使計算機能夠相互連接并傳輸資料,稱為通信協議,
TCP是一種面向連接的協議,它在主機之間建立并維護虛擬連接,直到交換了一條訊息或要在其上運行的應用程式交換的訊息為止,資料包是TCP/IP網路上資料傳輸的最基本單位,
TCP在傳輸層上運行,負責維護整個網路上可靠的端到端通信,IP是網路層協議,它是傳輸層正下方的層,在傳輸層運行的有:UDP(用戶資料報協議),RTP(實時傳輸協議),SCTP(流控制傳輸協議),
連接創建

- TCP用三次握手程序創建一個連接
三次握手協議的程序:
a.客戶端 向 服務器端 發送一個 SYN 包,請求一個主動打開,該包攜帶客戶端為這個連接請求設定的亂數A作為訊息列號,
b.服務器端接收到一個SYN包后,把該包放入SYN佇列中;回送一個SYN/ACK,ACK的確認碼應為A+1,SYN/ACK包本身攜帶一個隨機產生的序號B,
c.客戶端收到SYN/ACK包后,發送一個ACK的包,該包的序號被設定為A+1,而ACK的確認碼為B+1, 當服務器端收到這個ACK包的時候,把請求幀從SYN佇列中移出,放置ACCEPT佇列中,
場景:當服務器端接收到客戶端發送過來的SYN后, 回了SYN-ACK后,客戶端掉線了,服務器端沒有收到客戶端回來的ACK,那這個連接 就 處于 一個中間狀態,沒成功也沒失敗,
但是,服務器端如果在一定時間內沒有收到TCP會重新發SYN-ACK,
- 主機收到一個TCP包時,用兩端的IP地址與埠號來標識這個TCP包屬于哪個session,
- 使用一張表來存盤所有的session,表中的每條稱作TCB,
- tcb結構的定義含: 連接使用的源埠, 目的埠,目的ip, 序號, 應答序號, 對方視窗大小, 已方視窗大小, tcp狀態, tcp輸入/輸出佇列, 應用層輸出佇列, tcp的重傳有關變數等,
- 服務器端的連接數量是無限的,只受記憶體的限制,
資料傳送
在每個TCP報文段中都有一對序號和確認號,
TCP報文發送者稱自己的位元組流的編號為序號,稱接收到對方的位元組流編號為確認號,通過使用序號和確認號,TCP層可以把收到的報文段中的位元組按正確的順序交付給應用層,
TCP協議使用序號標識每端發出的位元組順序,從另一端接收資料可以重建順序,無懼傳輸的包的亂序交付或丟包,
發送確認包acks,攜帶接收對方發來的位元組流的編號(確認號),告訴對方已經成功接收的資料流的位元組位置,

上圖描述資料傳輸的程序圖
資料包結構
下面讓我們來看看資料包結構圖:

包含:偏移位元組,來源連接埠,目的連接埠,序列號碼,確認號碼,校驗和,緊急指標等,
- 來源連接埠,16位長,識別發送連接埠
- 目的連接埠,16位長,識別接收連接埠
- 序列號(
seq,32位長) - 確認號(
ack,32位長),期望收到的資料的開始序列號,也即已經收到的資料的位元組長度加1 - 資料偏移(4位長),以4位元組為單位計算出的資料段開始地址的偏移值,
- 保留,須置0
ACK—為1表示確認號欄位有效SYN—為1表示這是連接請求或是連接接受請求,用于創建連接和使順序號同步FIN—為1表示發送方沒有資料要傳輸了,要求釋放連接RST—為1表示出現嚴重差錯,可能需要重新創建TCP連接,還可以用于拒絕非法的報文段和拒絕連接請求- 緊急指標(16位長)—本報文段中的緊急資料的最后一個位元組的序號
- 視窗(
WIN,16位長)—表示從確認號開始,本報文的發送方可以接收的位元組數,即接收視窗大小,用于流量控制 - 校驗和(
Checksum,16位長)—對整個的TCP報文段,包括TCP頭部和TCP資料,以16位字進行計算所得,這是一個強制性的欄位
記住其中IP是把資料包送達目的主機的,資料包送達到主機,那么如何將資料包轉交給應用的呢?
UDP是把資料包送達應用程式的,
UDP是基于IP之上開發能和應用打交道的協議,用戶資料包協議,是決定把資料包交給哪個程式的,IP只負責把資料包傳送到對方電腦,
下面看一下UDP協議和TCP協議在TCP/IP體系中的位置:

看完位置,那么下面我們來簡單對比一下UDP和TCP:
UDP: 無連接;支持一對一,一對多,多對一和多對多互動通信;對應用層交付的報文直接打包;盡最大努力交付,也就是不可靠;不使用流量控制和擁塞控制;首部開銷小,僅8位元組,
TCP:面向連接;每一條TCP連接只能有兩個端點EP,只能是一對一通信;面向位元組流;可靠傳輸,使用流量控制和擁塞控制;首部最小20位元組,最大60位元組,
讓我們看看UDP和TCP首部對比開銷:

UDP最重要的一點就是埠號,因為UDP是通過埠號把資料包分發給正確的程式,UDP不能保證資料的可靠性,但傳輸速度快,
重要的講解是:資料是如何被完整地送達到應用程式?
TCP就是把資料完整地送達應用程式,
TCP是一種面向連接的,可靠的,基于位元組流的傳輸層通信協議,提供重傳機制,引入了資料包排序機制(TCP頭,提供了排序的序列號,用來通過序號重排資料包),
說到TCP連接,就要說說常面試的TCP/IP的三次握手,建立連接;四次揮手,斷開連接,
三次握手圖:

完成了三次TCP握手:
女朋友發給男朋友:“在嗎?”
男朋友回復女朋友:“我在!”
女朋友回復男朋友:“我知道了!”
此時男朋友知道了,
四次揮手圖:

完成四次揮手:
女朋友發給男朋友:“分手吧!”
男朋友回復女朋友:“額?”
男朋友回復女朋友:“認真的嗎?”
女朋友回復男朋友:“認真的!”
此時女朋友洗掉了男朋友的微信,
按照我描述的三次握手和四次揮手,我相信你懂了,哈哈!
第三問:HTTP請求流程,為什么很多站點第二次打開速度會很快呢?
說到HTTP協議,它是建立在TCP連接基礎之上的,超文本傳輸協議,HTTP是一種用于分布式,協作式和超媒體資訊系統的應用層協議,HTTP是萬維網的資料通信的基礎,
某人說:要想學好瀏覽器,就要深入了解HTTP,
瀏覽器是使用HTTP協議作為應用層協議,用來封裝請求的文本資訊,使用TCP/IP作傳輸層協議將它發到網路上(http的內容是通過TCP的傳輸資料階段來實作的),
- 域名和IP地址-映射關系,域名映射為IP的系統叫作**“域名系統”**,簡稱
DNS,
域名系統DNS是互聯網的一項服務,它作為將域名和IP地址相互映射的一個分布式資料庫,能夠使人更方便地訪問互聯網,
域名如:dadaqianduan.cn (URL地址)
IP地址為:xx.233.xxs.12 (訪問)
首先,第一步瀏覽器會請求DNS回傳域名對應的IP,瀏覽器還提供了DNS資料快取服務,如果某個域名已經被決議過了,瀏覽器就會快取決議的結構,下次查詢時直接使用,減少一次網路請求,拿到IP后,就需要獲取埠號,如果url沒有明確指出埠號,HTTP協議默認是80埠,
到這一步明白的清清楚楚了,IP和埠號,那么讓我說說HTTP協議的描述,這里補充是為了更好的了解:
HTTP是一個客戶端和服務器端之間請求和應答的標準,通常使用TCP協議,通過使用網頁瀏覽器,網咯爬蟲或者其它的工具,客戶端發起一個HTTP請求到服務器上指定埠,默認埠為80,
應答的服務器上存盤著一些資源,如HTML檔案和影像等,源服務器;(客戶端稱為用戶代理程式),用戶代理和源服務器中間可能存在多個"中間層",比如代理服務器,網關,隧道等,
so,HTTP服務器在埠監聽客戶端的請求,一旦收到請求,服務器會向客戶端回傳一個狀態,如:"HTTP/1.1 200 OK",以及回傳的內容,如請求的檔案,錯誤訊息,或者其它訊息,
到這里我先回答一下:瀏覽器發起HTTP請求流程:1.構建請求(構建請求行資訊);2.查找快取(瀏覽器快取是一種在本地保存資源副本,以供下次請求時直接使用的技術);3.準備IP地址和埠;4.等待TCP佇列;5.建立TCP連接;6.發送HTTP請求,
然后服務器處理請求,服務器回傳請求,斷開連接,
其實埠和IP地址準備好后,不一定直接建立TCP連接的,因為在Chrome中有個機制,就是同一個域名同時最多只能建立6個TCP連接,如果在同一個域名下同時有10個請求發生,那么其中就有4個請求進入排隊等待狀態,
如果請求數量少于6個,就直接進入建立TCP連接,
發送HTTP請求
上面都講好了初步,那么瀏覽器是如何發送請求資訊給服務器的呢?
來一張post請求抓包圖:

來張瀏覽器發送請求到服務器端接識訓傳的程序:

描述:用戶在瀏覽器輸入請求的url地址,瀏覽器內部的核心代碼會將這個url進行拆分決議,最終將domain發送到DNS服務器上,DNS服務器會根據domain去查詢相關的對應的ip地址,從而將IP地址回傳給瀏覽器,
瀏覽器有了ip地址后就會知道這個請求是發送到哪里的,經過(局域網,交換機,路由器,主干網咯)到達服務器,
對于經常了解HTTP的朋友應該了解上述表達,那接下來看看HTTP請求資料格式(可看上圖->來一張post請求抓包圖):
HTTP請求資料格式:
瀏覽器首先向服務器發送請求行(請求方法;請求URI;HTTP協議版本)-來告訴服務器瀏覽器需要什么資源,常用請求方法為GET,請求頭(用來告訴一些瀏覽器的基礎資訊-瀏覽器所使用的作業系統、瀏覽器內核等資訊,以及當前請求的域名資訊、瀏覽器端的Cookie資訊等),請求體(如常用的POST,用于發送一些資料給服務器,準備的資料是通過請求體來發送的),
服務器處理HTTP請求流程:
- 回傳請求;
- 斷開連接;
- 重定向,

查看回傳請求資料,-i,獲取回傳回應行(包含協議版本和狀態碼),回應頭,回應體資料,
一般情況下,服務器向客戶端回傳了請求資料,就要關閉TCP連接,但其頭資訊中加入了該欄位:Connection: Keep-Alive,讓TCP連接仍然保持連接,可以繼續同一個TCP連接發送請求,可以省下次請求時需要建立連接的時間,
其實一般回傳請求,斷開連接就沒了,但有一種就是你在瀏覽器中打開的url,發現最終的頁面地址不一樣,那是因為有一個重定向操作,
如圖:-I表示只需要獲取回應頭和回應行資料

- location欄位時重定向的地址;
狀態碼301和302的區別
301 Moved Permanently 被請求的資源已永久移動到新位置,并且將來任何對此資源的參考都應該使用本回應回傳的若干個URI之一,如果可能,擁有鏈接編輯功能的客戶端應當自動把請求的地址修改為從服務器反饋回來的地址,除非額外指定,否則這個回應也是可快取的,
302 Found 請求的資源現在臨時從不同的URI回應請求,由于這樣的重定向是臨時的,客戶端應當繼續向原有地址發送以后的請求,只有在Cache-Control或Expires中進行了指定的情況下,這個回應才是可快取的,
字面上的區別:301是永久重定向,而302是臨時重定向
302重定向是暫時的重定向,搜索引擎會抓取新的內容而保留舊的地址,因為服務器回傳302,所以搜索搜索引擎認為新的網址是暫時的,
301重定向是永久的重定向,搜索引擎在抓取新的內容的同時也將舊的網址替換為了重定向之后的網址,
接下來,讓我們梳理一下HTTP版本號,這一點,我相信在學習的程序中,大家也是想知道的,
HTTP/0.9:
已過時,僅支持請求方式GET,并且僅能請求訪問HTML格式的資源,沒有在通訊中指定版本號,且不支持請求頭,
HTTP/1.0:
這是第一個在通訊中指定版本號的HTTP協議版本,增加了請求方式POST和HEAD;不再局限于0.9版本的HTML格式,根據Content-Type可以支持多種資料格式;包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、快取(cache)、內容編碼(content encoding)等,
1.0版本:每次TCP連接只能發送一個請求,當服務器回應后就會關閉這次連接,下一個請求需要再次建立TCP連接.
HTTP/1.1:
默認采用持續連接(TCP連接默認不關閉,可以被多個請求復用,不用宣告Connection: keep-alive),能很好地配合代理服務器作業,
一個TCP連接可以允許多個HTTP請求
增加了管道機制,在同一個TCP連接里,允許多個請求同時發送,增加了并發性,進一步改善了HTTP協議的效率
1.1版規定可以不使用Content-Length欄位,而使用"分塊傳輸編碼"-只要請求或回應的頭資訊有Transfer-Encoding欄位,就表明回應將由數量未定的資料塊組成,Transfer-Encoding: chunked
新增了請求方式PUT、PATCH、OPTIONS、DELETE等
- 分塊傳輸編碼:是超文本傳輸協議中的一種資料傳輸機制,允許HTTP由網頁服務器發送給客戶端應用的資料可以分成多個部分,分塊傳輸編碼只在
HTTP協議1.1版本(HTTP/1.1)中提供,
同一個TCP連接里,所有的資料通信是按次序進行的,回應慢,會有許多請求排隊,造成"隊頭堵塞",
HTTP/2:
于2015年5月作為互聯網標準正式發布,加了雙工模式,即不僅客戶端能夠同時發送多個請求,服務端也能同時處理多個請求,解決了隊頭堵塞的問題,
使用了多路復用的技術,做到同一個連接并發處理多個請求,而且并發請求的數量比HTTP1.1大了好幾個數量級,
增加服務器推送的功能,不經請求服務端主動向客戶端發送資料,
HTTP1.1相較于HTTP1.0協議區別:
- 快取處理
- 帶寬優化及網路連接的使用
- 錯誤通知的管理
- 訊息在網路中的發送
- 互聯網地址的維護
- 安全性及完整性
最后的最后,說第二次站點的打開為啥速度快?
原因是第一次加載頁面程序中,快取了一些耗時的資料,主要快取有 DNS快取 和 頁面資源快取 兩個方面,
- 瀏覽器快取
當第一次發送請求,服務器回傳HTTP回應頭給瀏覽器時,瀏覽器會通過回應頭中CacheControl欄位來設定是否快取資源,通常還需設定一個快取時間,Cache-Control:Max-age=2000,在快取沒有過期的情況下,在發送請求請求該資源,會直接回傳快取中的資源給瀏覽器,如果快取過期,瀏覽器則會繼續發起網路請求,
盲點:

第四問:輸入URL到頁面展示發生了什么?
簡單地說一下就是:
- 瀏覽器主行程提交
url給網路行程 - 網路行程請求服務器,回傳回應頭行體,判斷是否需要重定向
- 網路行程將頁面型別的回應資源提交給渲染行程
- 渲染行程渲染結束,加載完畢
分步驟簡單說一下就是:
- 首先是域名決議
- 建立TCP鏈接
- 建立Http請求
- 服務器處理Http請求
- 關閉TCP連接
- 瀏覽器決議資源
- 瀏覽器渲染頁面
在我的GitHub上也講過:
從瀏覽器地址欄輸入url到顯示頁面的步驟
https://github.com/webVueBlog/interview-answe/issues/27
本篇文章的最后,留給你一個面試題,就是上面說到的:“從輸入URL到頁面展示,這中間發送了什么?”這個問題,如果面試你,你又如何回答呢?
如果你作為面試官,又該考哪些點呢?
閱讀資料
瀏覽器作業原理與實踐
https://time.geekbang.org/column/intro/100033601
總結
以上就是今天要講的內容,本文簡單介紹了Chrome流程,梳理了TCP與HTTP協議,了解三次握手,四次揮手流程,感謝閱讀,如果你覺得這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,
喜歡本文的朋友,歡迎關注,收看更多精彩內容
CSDN認證博客專家
CSDN博客專家
簡書萬粉優秀創作
掘金優秀作者
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/229183.html
標籤:其他
