【HTTP】HTTP 的15個常見知識點複習

封面

前言

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

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

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

📅推薦一個 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 需要三次握手才能建立,而斷開連接則需要四次握手。整個過程如下圖所示:

http3

TCP三次握手

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

http1

TCP四次揮手:

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

http2

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響應頭和請求頭信息對照表》

首部字段名 說明
Accept 告訴服務器,客戶端支持的數據類型。
Accept-Charset 告訴服務器,客戶端採用的編碼。
Accept-Encoding 告訴服務器,客戶機支持的數據壓縮格式。
Accept-Language 告訴服務器,客戶機的語言環境。
Host 客戶機通過這個頭告訴服務器,想訪問的主機名。
If-Modified-Since 客戶機通過這個頭告訴服務器,資源的緩存時間。
Referer 客戶機通過這個頭告訴服務器,它是從哪個資源來訪問服務器的。(一般用於防盜鏈)
User-Agent 客戶機通過這個頭告訴服務器,客戶機的軟件環境。
Cookie 客戶機通過這個頭告訴服務器,可以向服務器帶數據。
Connection 客戶機通過這個頭告訴服務器,請求完後是關閉還是保持鏈接。
Date 客戶機通過這個頭告訴服務器,客戶機當前請求時間

3.2 Request Header

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

舉例:

Request Header 描述
GET /sample.Jsp HTTP/1.1 請求行
Host: www.uuid.online/ 請求的目標域名和端口號
Origin: http://localhost:8081/ 請求的來源域名和端口號 (跨域請求時,瀏覽器會自動帶上這個頭信息)
Referer: https:/localhost:8081/link?query=xxxxx 請求資源的完整URI
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 瀏覽器信息
Cookie: BAIDUID=FA89F036:FG=1; BD_HOME=1; sugstore=0 當前域名下的Cookie
Accept: text/html,image/apng 代表客戶端希望接受的數據類型是html或者是png圖片類型
Accept-Encoding: gzip, deflate 代表客戶端能支持 gzip 和 deflate 格式的壓縮
Accept-Language: zh-CN,zh;q=0.9 代表客戶端可以支持語言 zh-CN 或者 zh (值得一提的是q(0~1)是優先級權重的意思,不寫默認爲1,這裏 zh-CN 是1, zh 是0.9)
Connection: keep-alive 告訴服務器,客戶端需要的 tcp 連接是一個長連接

3.3 Response Header

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

舉例:

Response Header 描述
HTTP/1.1 200 OK 響應狀態行
Date: Mon, 30 Jul 2018 02:50:55 GMT 服務端發送資源時的服務器時間
Expires: Wed, 31 Dec 1969 23:59:59 GMT 較過時的一種驗證緩存的方式,與瀏覽器(客戶端)的時間比較,超過這個時間就不用緩存(不和服務器進行驗證),適合版本比較穩定的網頁
Cache-Control: no-cache 現在最多使用的控制緩存的方式,會和服務器進行緩存驗
etag: "fb8ba2f80b1d324bb997cbe188f28187-ssl-df" 一般是Nginx靜態服務器發來的靜態文件簽名,瀏覽在沒有 “Disabled cache” 情況下,接收到 etag 後,同一個 url 第二次請求就會自動帶上 “If-None-Match”
Last-Modified: Fri, 27 Jul 2018 11:04:55 GMT 服務器發來的當前資源最後一次修改的時間,下次請求時,如果服務器上當前資源的修改時間大於這個時間,就返回新的資源內容
Content-Type: text/html; charset=utf-8 如果返回是流式的數據,我們就必須告訴瀏覽器這個頭,不然瀏覽器會下載這個頁面,同時告訴瀏覽器是utf8編碼,否則可能出現亂碼
Content-Encoding: gzip 告訴客戶端,應該採用gzip對資源進行解碼
Connection: keep-alive 告訴客戶端服務器的tcp連接也是一個長連接

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 方法。

序號 方法 描述
1 GET 請求指定的頁面信息,並返回實體主體。
2 HEAD 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
3 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
4 PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。
5 DELETE 請求服務器刪除指定的頁面。
6 CONNECT HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。
7 OPTIONS 允許客戶端查看服務器的性能。
8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。
9 PATCH 實體中包含一個表,表中說明與該URI所表示的原內容的區別。
10 MOVE 請求服務器將指定的頁面移至另一個網絡地址。
11 COPY 請求服務器將指定的頁面拷貝至另一個網絡地址。
12 LINK 請求服務器建立鏈接關係。
13 UNLINK 斷開鏈接關係。
14 WRAPPED 允許客戶端發送經過封裝的請求。
15 Extension-mothed 在不改動協議的前提下,可增加另外的方法。

4.2 GET 與 POST 請求之間的區別

區別內容 GET POST
點擊返回/刷新按鈕 沒有影響 數據會重新發送(瀏覽器將會提示“數據被重新提交”)
添加書籤 可以 不可以
緩存 可以 不可以
編碼類型(Encoding type) application/x-www-form-rulencoded application/x-www-form-rulencoded or multipart/form-data 請爲二進制數據使用 multipart 編碼
歷史記錄 沒有
長度限制 沒有
數據類型限制 只允許 ASCLll 字符類型 沒有限制,允許二進制數據
安全性 查詢字符串會顯示在地址欄的 URL 上,不安全,請不要使用 GET 請求提交敏感數據 因爲數據不會顯示在地址欄中,也不會緩存下來或保存在瀏覽記錄中,所以 POST 請求比 GET 請求安全,但也不是最安全的方式,如需要傳送敏感數據,請使用數據加密
可見性 查詢字符串在地址欄的 URL 中可見 查詢字符串在地址欄的 URL 中不可見

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

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

5.1 Cookie簡單介紹

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

http4

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

5.2 Session

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

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

http5

  • 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 請求報文

http6

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

  • 請求行

格式爲:

請求方法 + 空格 + 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 響應報文

http7

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

  • 狀態行

格式爲:

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

狀態碼劃分:

100〜199的狀態碼是 HTTP / 1.1 向協議中引入了信息性狀態碼
200〜299的狀態碼錶示成功
300〜399的狀態碼指資源重定向
400〜499的狀態碼指客戶端請求出錯
500〜599的狀態碼指服務端出錯

常見的狀態碼:

狀態碼 說明
200 響應成功
302 跳轉,跳轉地址通過響應頭中的位置屬性指定(JSP中Forward和Redirect之間的區別)
400 客戶端請求有語法錯誤,不能被服務器識別
403 服務器接收到請求,但是拒絕提供服務(認證失敗)
404 請求資源不存在
500 服務器內部錯誤
  • 響應頭部

格式爲:

頭部字段名 + 冒號(:) + 值 + 回車符 + 換行符

常見響應頭部:

響應頭部 說明
Server 服務器應用程序軟件的名稱和版本
Content-Type 響應正文的類型(是圖片還是二進制字符串)
Content-Length 響應正文長度
Content-Charset 響應正文使用的編碼
Content-Encoding 響應正文使用的數據壓縮格式
Content-Language 響應正文使用的語言

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 的性能限制,改進傳輸性能實現低延遲高吞吐量

http12

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

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

  • 多路複用(連接共享)

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

http11

從圖中可見,所有的 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。

http13

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

http14

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

http15

9.2 HTTPS 工作原理

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

http16

  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地址,也非同源。

  • 同源策略限制了以下行爲:
  1. CookieLocalStorageIndexDB 無法讀取
  2. DOMJS對象無法獲取
  3. 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 中與緩存相關的頭部有哪些,它們有什麼區別

頭部 優勢和特點 劣勢和問題
Expires 1、HTTP 1.0 產物,可以在HTTP 1.01.1中使用,簡單易用。2、以時刻標識失效時間。 1、時間是由服務器發送的(UTC),如果服務器時間和客戶端時間存在不一致,可能會出現問題。2、存在版本問題,到期之前的修改客戶端是不可知的。
Cache-Control 1、HTTP 1.1 產物,以時間間隔標識失效時間,解決了Expires服務器和客戶端相對時間的問題。2、比Expires多了很多選項設置。 1、HTTP 1.1纔有的內容,不適用於HTTP 1.0 。2、存在版本問題,到期之前的修改客戶端是不可知的。
Last-Modified 1、不存在版本問題,每次請求都會去服務器進行校驗。服務器對比最後修改時間如果相同則返回304,不同返回200以及資源內容。 1、只要資源修改,無論內容是否發生實質性的變化,都會將該資源返回客戶端。例如週期性重寫,這種情況下該資源包含的數據實際上一樣的。2、以時刻作爲標識,無法識別一秒內進行多次修改的情況。3、某些服務器不能精確的得到文件的最後修改時間。
ETag 1、可以更加精確的判斷資源是否被修改,可以識別一秒內多次修改的情況。2、不存在版本問題,每次請求都回去服務器進行校驗。 1、計算ETag值需要性能損耗。2、分佈式服務器存儲的情況下,計算ETag的算法如果不一樣,會導致瀏覽器從一臺服務器上獲得頁面內容後到另外一臺服務器上進行驗證時發現ETag不匹配的情況。

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 :資源在內存當中,一般腳本、字體、圖片會存在內存當

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

http17

http18

13.2 協商緩存

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

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

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

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

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

http19

http20

13.3 流程

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

1

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

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

2

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

參考文章:《LRU算法》

14.1 原理

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

http21

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

http22

14.2 實現

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

  1. 新數據插入到鏈表頭部;

  2. 每當緩存命中(即緩存數據被訪問),則將數據移到鏈表頭部;

  3. 當鏈表滿的時候,將鏈表尾部的數據丟棄。

14.3 分析

  • 命中率

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

  • 複雜度

實現簡單。

  • 代價

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

結語

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

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

關於我

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

Author 王平安
E-mail [email protected]
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推薦 https://github.com/pingan8787/Leo_Reading/issues
ES小冊 js.pingan8787.com

微信公衆號

bg

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章