面試題(2020)前端HTTP瀏覽器相關面試題
博客說明
文章所涉及的資料來自互聯網整理和個人總結,意在於個人學習和經驗匯總,如有什么地方侵權,請聯系本人刪除,謝謝!
1、HTTP1.1 是當前使用最為廣泛的HTTP協議
- HTTP1.0 和 HTTP1.1 相比
- HTTP1.0 定義了三種請求方法: GET, POST 和 HEAD 方法。HTTP1.1 新增了六種請求方法:OPTIONS、PUT、PATCH、DELETE、TRACE 和 CONNECT 方法。
- 緩存處理:在HTTP1.0中主要使用header里的If-Modified-Since,Expires來做為緩存判斷的標准,HTTP1.1則引入了更多的緩存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供選擇的緩存頭來控制緩存策略。
- 帶寬優化及網絡連接的使用:HTTP1.0中,存在一些浪費帶寬的現象,例如客戶端只是需要某個對象的一部分,而服務器卻將整個對象送過來了,並且不支持斷點續傳功能,HTTP1.1則在請求頭引入了range頭域,它允許只請求資源的某個部分,即返回碼是206(Partial Content),這樣就方便了開發者自由的選擇以便於充分利用帶寬和連接。
- 錯誤通知的管理:在HTTP1.1中新增了24個錯誤狀態響應碼,如409(Conflict)表示請求的資源與資源的當前狀態發生沖突;410(Gone)表示服務器上的某個資源被永久性的刪除。
- Host頭處理:在HTTP1.0中認為每台服務器都綁定一個唯一的IP地址,因此,請求消息中的URL並沒有傳遞主機名(hostname)。但隨着虛擬主機技術的發展,在一台物理服務器上可以存在多個虛擬主機(Multi-homed Web Servers),並且它們共享一個IP地址。HTTP1.1的請求消息和響應消息都應支持Host頭域,且請求消息中如果沒有Host頭域會報告一個錯誤(400 Bad Request)。
- 長連接:HTTP 1.1支持長連接(PersistentConnection)和請求的流水線(Pipelining)處理,在一個TCP連接上可以傳送多個HTTP請求和響應,減少了建立和關閉連接的消耗和延遲,在HTTP1.1中默認開啟Connection: keep-alive,一定程度上彌補了HTTP1.0每次請求都要創建連接的缺點。通過設置http的請求頭部和應答頭部,保證本次數據請求結束之后,下一次請求仍可以重用這一通道,避免重新握手。
- HTTP2.0 和 HTTP1.X 相比
- 新的二進制格式(Binary Format):HTTP1.x的解析是基於文本。基於文本協議的格式解析存在天然缺陷,文本的表現形式有多樣性,要做到健壯性考慮的場景必然很多,二進制則不同,只認0和1的組合。基於這種考慮HTTP2.0的協議解析決定采用二進制格式,實現方便且健壯。
- 多路復用(MultiPlexing):即連接共享,即每一個request都是是用作連接共享機制的。一個request對應一個id,這樣一個連接上可以有多個request,每個連接的request可以隨機的混雜在一起,接收方可以根據request的 id將request再歸屬到各自不同的服務端請求里面。
- header壓縮:如上文中所言,對前面提到過HTTP1.x的header帶有大量信息,而且每次都要重復發送,HTTP2.0使用了專門為首部壓縮而設計的 HPACK 算法,使用encoder來減少需要傳輸的header大小,通訊雙方各自cache一份header fields表,既避免了重復header的傳輸,又減小了需要傳輸的大小。
- 服務端推送(server push):服務端推送能把客戶端所需要的資源伴隨着index.html一起發送到客戶端,省去了客戶端重復請求的步驟。正因為沒有發起請求,建立連接等操作,所以靜態資源通過服務端推送的方式可以極大地提升速度。例如我的網頁有一個sytle.css的請求,在客戶端收到sytle.css數據的同時,服務端會將sytle.js的文件推送給客戶端,當客戶端再次嘗試獲取sytle.js時就可以直接從緩存中獲取到,不用再發請求了。
- HTTPS 與 HTTP 相比
- HTTPS協議需要到CA申請證書,一般免費證書很少,需要交費。
- HTTP協議運行在TCP之上,所有傳輸的內容都是明文,HTTPS運行在SSL/TLS之上,SSL/TLS運行在TCP之上,所有傳輸的內容都經過加密的。
- HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
- HTTPS可以有效的防止運營商劫持,解決了防劫持的一個大問題。
2、HTTPS 介紹
HTTPS在傳輸數據之前需要客戶端(瀏覽器)與服務端(網站)之間進行一次握手,在握手過程中將確立雙方加密傳輸數據的密碼信息。TLS/SSL協議不僅僅是一套加密傳輸的協議,TLS/SSL中使用了非對稱加密,對稱加密以及HASH算法
3、HTTPS握手過程的簡單描述如下:
1、瀏覽器將自己支持的一套加密規則發送給網站。
2、網站從中選出一組加密算法與HASH算法,並將自己的身份信息以證書的形式發回給瀏覽器。證書里面包含了網站地址,加密公鑰,以及證書的頒發機構等信息。
3、獲得網站證書之后瀏覽器要做以下工作:
a. 驗證證書的合法性(頒發證書的機構是否合法,證書中包含的網站地址是否與正在訪問的地址一致等),如果證書受信任,則瀏覽器欄里面會顯示一個小鎖頭,否則會給出證書不受信的提示。
b. 如果證書受信任,或者是用戶接受了不受信的證書,瀏覽器會生成一串隨機數的密碼,並用證書中提供的公鑰加密。
c. 使用約定好的HASH計算握手消息,並使用生成的隨機數對消息進行加密,最后將之前生成的所有信息發送給網站。
4、網站接收瀏覽器發來的數據之后要做以下的操作:
a. 使用自己的私鑰將信息解密取出密碼,使用密碼解密瀏覽器發來的握手消息,並驗證HASH是否與瀏覽器發來的一致。
b. 使用密碼加密一段握手消息,發送給瀏覽器。
5、瀏覽器解密並計算握手消息的HASH,如果與服務端發來的HASH一致,此時握手過程結束,之后所有的通信數據將由之前瀏覽器生成的隨機密碼並利用對稱加密算法進行加密。
4、cookie和session的機制是什么?有什么區別?
session 是基於 cookie 實現的。cookie 保存在客戶端瀏覽器中,而 session 保存在服務器上。cookie 機制是通過檢查客戶身上的“通行證”來確定客戶身份的話,那么 session 機制就是通過檢查服務器上的“客戶明細表”來確認客戶身份。session 相當於程序在服務器上建立的一份客戶檔案,客戶來訪的時候只需要查詢客戶檔案表就可以了。
cookie 和 session 的區別:
- 存在的位置:
cookie 存在於客戶端,臨時文件夾中;session 存在於服務器的內存中,一個 session 域對象為一個用戶瀏覽器服務 - 安全性
cookie 是以明文的方式存放在客戶端的,安全性低,可以通過一個加密算法進行加密后存放;session 存放於服務器的內存中,所以安全性好 - 生命周期(以 20 分鍾為例)
cookie 的生命周期是累計的,從創建時,就開始計時,20 分鍾后 cookie 生命周期結束;
session 的生命周期是間隔的,從創建時,開始計時如在 20 分鍾,沒有訪問 session,那么 session 生命周期被銷毀。但是,如果在 20 分鍾內(如在第 19 分鍾時)訪問過 session,那么,將重新計算 session 的生命周期。關機會造成 session 生命周期的結束,但是對 cookie 沒有影響 - 訪問范圍
cookie 為多個用戶瀏覽器共享;session 為一個用戶瀏覽器獨享
5、瀏覽器的存儲
特性 | cookie | localStorage | sessionStorage | indexedDB |
---|---|---|---|---|
數據生命周期 | 一般由服務器生成,可以設置過期時間 | 除非被清理,否則一直存在 | 頁面關閉就清理 | 除非被清理,否則一直存在 |
數據存儲大小 | 4K | 5M | 5M | 無限 |
與服務端通信 | 每次都會攜帶在 header,中,對於請求性能影響 | 不參與 | 不參與 | 不參與 |
補充:cookie 原本並不是用來儲存的,而是用來與服務端通信的,需要存取請自行封裝 api。
而 localStorage 則自帶 getItem 和 setItem 方法,使用很方便。
localStorage 注意點:
- localStorage 只能存字符串,存取 JSON 數據需配合 JSON.stringify() 和 JSON.parse()
- 遇上禁用 setItem 的瀏覽器,需要使用 try...catch 捕獲異常
6、輸入URL發生什么?
- DNS 域名解析(域名解析成ip地址,走UTP協議,因此不會有握手過程):瀏覽器將 URL 解析出相對應的服務器的 IP 地址(1. 本地瀏覽器的 DNS 緩存中查找 2. 再向系統DNS緩存發送查詢請求 3. 再向路由器DNS緩存 4. 網絡運營商DNS緩存 5. 遞歸搜索),並從 url 中解析出端口號
- 瀏覽器與目標服務器建立一條 TCP 連接(三次握手)
- 瀏覽器向服務器發送一條 HTTP 請求報文
- 服務器返回給瀏覽器一條 HTTP 響應報文
- 瀏覽器進行渲染
- 關閉 TCP 連接(四次揮手)
7、瀏覽器渲染的步驟
- HTML 解析出 DOM Tree
- CSS 解析出 Style Rules
- 兩者關聯生成 Render Tree
- Layout(布局)根據 Render Tree 計算每個節點的信息
- Painting 根據計算好的信息進行渲染整個頁面
瀏覽器解析文檔的過程中,如果遇到 script 標簽,會立即解析腳本,停止解析文檔(因為 JS 可能會改變 DOM 和 CSS,如果繼續解析會造成浪費)。
如果是外部 script, 會等待腳本下載完成之后在繼續解析文檔。現在 script 標簽增加了 defer 和 async 屬性,腳本解析會將腳本中改變 DOM 和 css 的地方> 解析出來,追加到 DOM Tree 和 Style Rules 上
8、什么是同源策略及其限制內容?
同源策略是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSS、CSRF等攻擊。所謂同源是指"協議+域名+端口"三者相同,即便兩個不同的域名指向同一個ip地址,也非同源。
9、同源策略限制內容有:
- Cookie、LocalStorage、IndexedDB 等存儲性內容
- DOM 節點
- AJAX 請求發送后,結果被瀏覽器攔截了
但是有三個標簽是允許跨域加載資源:
<img src=XXX>
<link href=XXX>
<script src=XXX>
10、跨域解決方案
1.jsonp
利用 <script>
標簽沒有跨域限制的漏洞,網頁可以得到從其他來源動態產生的 JSON 數據。JSONP請求一定需要對方的服務器做支持才可以。
2.cors
CORS 需要瀏覽器和后端同時支持。IE 8 和 9 需要通過 XDomainRequest 來實現。
瀏覽器會自動進行 CORS 通信,實現 CORS 通信的關鍵是后端。只要后端實現了 CORS,就實現了跨域。
3、postMessage
postMessage()方法允許來自不同源的腳本采用異步方式進行有限的通信,可以實現跨文本檔、多窗口、跨域消息傳遞。
4、websocket
WebSocket 是一種雙向通信協議,在建立連接之后,WebSocket 的 server 與 client 都能主動向對方發送或接收數據
5.nginx反向代理
實現原理類似於Node中間件代理,需要你搭建一個中轉nginx服務器,用於轉發請求。
6、iframe
11、頁面渲染優化
基於對渲染過程的了解,推薦一下優化:
- HTML 文檔結構層次盡量少,最好不深於 6 層
- 腳本盡量放后邊,避免組織頁面加載
- 少量首屏樣式可以放在便簽內
- 樣式結構層次盡量簡單
- 腳本減少 DOM 操作,減少回流,盡量緩存訪問 DOM 的樣式信息
- 盡量減少 JS 修改樣式,可以通過修改 class 名的方式解決
- 減少 DOM 查找,緩存 DOM 查找結果
- 動畫在屏幕外或頁面滾動時,盡量停止
12、強制緩存和協商緩存
- 強制緩存是我們在第一次請求資源時在 http 響應頭設置一個過期時間,在時效內都將直接從瀏覽器進行獲取,常見的 http 響應頭字段如 Cache-Control 和 Expires
- 協商緩存是我們通過 http 響應頭字段 etag 或者 Last-Modified 等判斷服務器上資源是否修改,如果修改則從服務器重新獲取,如果未修改則 304 指向瀏覽器緩存中進行獲取
13、GET 和 POST 請求的區別
- GET 參數通過 url 傳遞,POST 放在 body 中。(http 協議規定,url 在請求頭中,所以大小限制很小)
- GET 請求在 url 中傳遞的參數是有長度限制的,而 POST 沒有。
- GET 在瀏覽器回退時是無害的,而 POST 會再次提交請求
- GET 請求會被瀏覽器主動 cache,而 POST 不會,除非手動設置
- GET 比 POST 更不安全,因為參數直接暴露在 url 中,所以不能用來傳遞敏感信息
- 對參數的數據類型,GET 只接受 ASCII字符,而 POST 沒有限制
- GET 請求只能進行 url(x-www-form-urlencoded)編碼,而 POST 支持多種編碼方式
- GET 產生一個 TCP 數據包;POST 產生兩個 TCP 數據包。對於 GET 方式的請求,瀏覽器會把 http 的 header 和 data 一並發送出去,服務器響應200(返回數據)。而對於 POST,瀏覽器先發送 header,服務器響應100 continue,瀏覽器再發送 data,服務器響應200 ok(返回數據)
14、介紹下304過程
a. 瀏覽器請求資源時首先命中資源的Expires 和 Cache-Control,Expires 受限於本地時間,如果修改了本地時間,可能會造成緩存失效,可以通過Cache-control: max-age指定最大生命周期,狀態仍然返回200,但不會請求數據,在瀏覽器中能明顯看到from cache字樣。
b. 強緩存失效,進入協商緩存階段,首先驗證ETagETag可以保證每一個資源是唯一的,資源變化都會導致ETag變化。服務器根據客戶端上送的If-None-Match值來判斷是否命中緩存。
c. 協商緩存Last-Modify/If-Modify-Since階段,客戶端第一次請求資源時,服務服返回的header中會加上Last-Modify,Last-modify是一個時間標識該資源的最后修改時間。再次請求該資源時,request的請求頭中會包含If-Modify-Since,該值為緩存之前返回的Last-Modify。服務器收到If-Modify-Since后,根據資源的最后修改時間判斷是否命中緩存。
15、HTTP 狀態碼
- 1xx(臨時響應)表示臨時響應並需要請求者繼續執行操作的狀態碼
- 100 - 繼續 請求者應當繼續提出請求。服務器返回此代碼表示已收到請求的第一部分,正在等待其余部分
- 101 - 切換協議 請求者已要求服務器切換協議,服務器已確認並准備切換
- 2xx(成功)表示成功處理了請求的狀態碼
- 200 - 成功 服務器已經成功處理了請求。通常,這表示服務器提供了請求的網頁
- 201 - 已創建 請求成功並且服務器創建了新的資源
- 202 - 已接受 服務器已接受請求,但尚未處理
- 203 - 非授權信息 服務器已經成功處理了請求,但返回的信息可能來自另一來源
- 204 - 無內容 服務器成功處理了請求,但沒有返回任何內容
- 205 - 重置內容 服務器成功處理了請求,但沒有返回任何內容
- 206 - 部分內容 服務器成功處理了部分GET請求
- 3xx(重定向)表示要完成請求,需要進一步操作;通常,這些狀態代碼用來重定向
- 300 - 多種選擇 針對請求,服務器可執行多種操作。服務器可根據請求者(user agent)選擇一項操作,或提供操作列表供請求者選擇
- 301 - 永久移動 請求的網頁已永久移動到新位置。服務器返回此響應(對GET或HEAD請求的響應)時,會自動將請求者轉到新位置
- 302 - 臨時移動 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有位置來進行以后的請求
- 303 - 查看其它位置 請求者應當對不同的位置使用單獨的GET請求來檢索響應時,服務器返回此代碼
- 304 - 未修改 自上次請求后,請求的網頁未修改過。服務器返回此響應,不會返回網頁的內容
- 305 - 使用代理 請求者只能使用代理訪問請求的網頁。如果服務器返回此響應,還表示請求者應使用代理
- 307 - 臨時性重定向 服務器目前從不同位置的網頁響應請求,但請求者應繼續使用原有的位置來進行以后的請求
- 4xx(請求錯誤)這些狀態碼表示請求可能出錯,妨礙了服務器的處理
- 400 - 錯誤請求 服務器不理解請求的語法
- 401 - 未授權 請求要求身份驗證。對於需要登錄的網頁,服務器可能返回此響應
- 403 - 禁止 服務器拒絕請求
- 404 - 未找到 服務器找不到請求的網頁
- 405 - 方法禁用 禁用請求中指定的方法
- 406 - 不接受 無法使用請求的內容特性響應請求的網頁
- 407 - 需要代理授權 此狀態碼與401(未授權)類似,但指定請求者應當授權使用代理
- 408 - 請求超時 服務器等候請求時發生超時
- 409 - 沖突 服務器在完成請求時發生沖突。服務器必須在響應中包含有關沖突的信息
- 410 - 已刪除 如果請求的資源已永久刪除,服務器就會返回此響應
- 411 - 需要有效長度 服務器不接受不含有效內容長度標頭字段的請求
- 412 - 未滿足前提條件 服務器未滿足請求者在請求者設置的其中一個前提條件
- 413 - 請求實體過大 服務器無法處理請求,因為請求實體過大,超出了服務器的處理能力
- 414 - 請求的URI過長 請求的URI(通常為網址)過長,服務器無法處理
- 415 - 不支持媒體類型 請求的格式不受請求頁面的支持
- 416 - 請求范圍不符合要求 如果頁面無法提供請求的范圍,則服務器會返回此狀態碼
- 417 - 未滿足期望值 服務器未滿足“期望”請求標頭字段的要求
- 5xx(服務器錯誤)這些狀態碼表示服務器在嘗試處理請求時發生內部錯誤。這些錯誤可能是服務器本身的錯誤,而不是請求出錯
- 500 - 服務器內部錯誤 服務器遇到錯誤,無法完成請求
- 501 - 尚未實施 服務器不具備完成請求的功能。例如,服務器無法識別請求方法時可能會返回此代碼
- 502 - 錯誤網關 服務器作為網關或代理,從上游服務器無法收到無效響應
- 503 - 服務器不可用 服務器目前無法使用(由於超載或者停機維護)。通常,這只是暫時狀態
- 504 - 網關超時 服務器作為網關代理,但是沒有及時從上游服務器收到請求
- 505 - HTTP版本不受支持 服務器不支持請求中所用的HTTP協議版本
感謝
萬能的網絡