【HTTP】267- HTTP 的15個(gè)常見知識點(diǎn)復(fù)習(xí)
前言
自從入職新公司到現(xiàn)在,我們前端團(tuán)隊(duì)內(nèi)部一直在做 ??每周一練?的知識復(fù)習(xí)計(jì)劃,我之前整理了一個(gè)?[每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法] (https://juejin.im/post/5ce2a20e6fb9a07ebb05061c)?學(xué)習(xí)內(nèi)容,大家也快去看看~~
最近三周,主要復(fù)習(xí)?網(wǎng)絡(luò)基礎(chǔ)?相關(guān)的知識,今天我把這三周復(fù)習(xí)的知識和參考答案,整理成本文,歡迎各位朋友互相學(xué)習(xí)和指點(diǎn),覺得本文不錯(cuò),也歡迎點(diǎn)贊哈????。
特別喜歡現(xiàn)在的每周學(xué)習(xí)和分享,哈哈哈~~??
??推薦一個(gè) github 倉庫 —— [《awesome-http》] (https://github.com/semlinker/awesome-http),內(nèi)容挺棒的。
注:本文整理資料來源網(wǎng)絡(luò),有些圖片/段落找不到原文出處,如有侵權(quán),聯(lián)系刪除。
一. 簡述瀏覽器輸入 URL 地址后發(fā)生的事情
1.1 描述
瀏覽器向 DNS 服務(wù)器查找輸入 URL 對應(yīng)的 IP 地址。
NS 服務(wù)器返回網(wǎng)站的 IP 地址。
瀏覽器根據(jù) IP 地址與目標(biāo) web 服務(wù)器在 80 端口上建立 TCP 連接。
瀏覽器獲取請求頁面的 HTML 代碼。
瀏覽器在顯示窗口內(nèi)渲染 HTML 。
窗口關(guān)閉時(shí),瀏覽器終止與服務(wù)器的連接。
1.2 TCP 知識點(diǎn)補(bǔ)充
參考文章:[《TCP三次握手和四次揮手協(xié)議》] (http://swiftlet.net/archives/1082)
建立 TCP 需要三次握手才能建立,而斷開連接則需要四次握手。整個(gè)過程如下圖所示:

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

TCP四次揮手:
TCP連接的拆除需要發(fā)送四個(gè)包,客戶端或者服務(wù)器端均可主動發(fā)起揮手動作,在SOCKET編程中,任何一方執(zhí)行close()即可產(chǎn)生揮手操作。

2. 請介紹常見的 HTTP 狀態(tài)碼(至少五個(gè))
狀態(tài)碼是由 3 位數(shù)組成,第一個(gè)數(shù)字定義了響應(yīng)的類別,且有五種可能取值:
1xx:指示信息–表示請求已接收,繼續(xù)處理。
100 客戶必須繼續(xù)發(fā)出請求
101 客戶要求服務(wù)器根據(jù)請求轉(zhuǎn)換HTTP協(xié)議版本
2xx:成功–表示請求已被成功接收、理解、接受。
200 (成功) 服務(wù)器已成功處理了請求。 通常,這表示服務(wù)器提供了請求的網(wǎng)頁。
201 (已創(chuàng)建) 請求成功并且服務(wù)器創(chuàng)建了新的資源。
202 (已接受) 服務(wù)器已接受請求,但尚未處理。
3xx:重定向–要完成請求必須進(jìn)行更進(jìn)一步的操作。
300 (多種選擇) 針對請求,服務(wù)器可執(zhí)行多種操作。 服務(wù)器可根據(jù)請求者 (user agent) 選擇一項(xiàng)操作,或提供操作列表供請求者選擇。
301 (永久移動) 請求的網(wǎng)頁已永久移動到新位置。 服務(wù)器返回此響應(yīng)(對 GET 或 HEAD 請求的響應(yīng))時(shí),會自動將請求者轉(zhuǎn)到新位置。
302 (臨時(shí)移動) 服務(wù)器目前從不同位置的網(wǎng)頁響應(yīng)請求,但請求者應(yīng)繼續(xù)使用原有位置來進(jìn)行以后的請求。
4xx:客戶端錯(cuò)誤–請求有語法錯(cuò)誤或請求無法實(shí)現(xiàn)。
400 (錯(cuò)誤請求) 服務(wù)器不理解請求的語法。
401 (未授權(quán)) 請求要求身份驗(yàn)證。 對于需要登錄的網(wǎng)頁,服務(wù)器可能返回此響應(yīng)。
403 (禁止) 服務(wù)器拒絕請求。
5xx:服務(wù)器端錯(cuò)誤–服務(wù)器未能實(shí)現(xiàn)合法的請求。
500 (服務(wù)器內(nèi)部錯(cuò)誤) 服務(wù)器遇到錯(cuò)誤,無法完成請求。
501 (尚未實(shí)施) 服務(wù)器不具備完成請求的功能。 例如,服務(wù)器無法識別請求方法時(shí)可能會返回此代碼。
502 (錯(cuò)誤網(wǎng)關(guān)) 服務(wù)器作為網(wǎng)關(guān)或代理,從上游服務(wù)器收到無效響應(yīng)。
503 (服務(wù)不可用) 服務(wù)器目前無法使用(由于超載或停機(jī)維護(hù))。 通常,這只是暫時(shí)狀態(tài)。
504 (網(wǎng)關(guān)超時(shí)) 服務(wù)器作為網(wǎng)關(guān)或代理,但是沒有及時(shí)從上游服務(wù)器收到請求。
505 (HTTP 版本不受支持) 服務(wù)器不支持請求中所用的 HTTP 協(xié)議版本。
3. 請介紹常見的 HTTP 頭部(至少五個(gè))
3.1 HTTP 頭部
更多完整內(nèi)容,可以查看 [《HTTP響應(yīng)頭和請求頭信息對照表》] (tools.jb51.net/table/http_header)
| 首部字段名 | 說明 |
|---|---|
Accept | 告訴服務(wù)器,客戶端支持的數(shù)據(jù)類型。 |
Accept-Charset | 告訴服務(wù)器,客戶端采用的編碼。 |
Accept-Encoding | 告訴服務(wù)器,客戶機(jī)支持的數(shù)據(jù)壓縮格式。 |
Accept-Language | 告訴服務(wù)器,客戶機(jī)的語言環(huán)境。 |
Host | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,想訪問的主機(jī)名。 |
If-Modified-Since | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,資源的緩存時(shí)間。 |
Referer | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,它是從哪個(gè)資源來訪問服務(wù)器的。(一般用于防盜鏈) |
User-Agent | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,客戶機(jī)的軟件環(huán)境。 |
Cookie | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,可以向服務(wù)器帶數(shù)據(jù)。 |
Connection | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,請求完后是關(guān)閉還是保持鏈接。 |
Date | 客戶機(jī)通過這個(gè)頭告訴服務(wù)器,客戶機(jī)當(dāng)前請求時(shí)間 |
3.2 Request Header
參考文章:[《HTTP常用頭部信息》] (https://www.cnblogs.com/amiezhang/p/9389840.html)
舉例:
| Request Header | 描述 |
|---|---|
GET/sample.JspHTTP/1.1 | 請求行 |
Host:www.uuid.online/ | 請求的目標(biāo)域名和端口號 |
Origin:http://localhost:8081/ | 請求的來源域名和端口號 (跨域請求時(shí),瀏覽器會自動帶上這個(gè)頭信息) |
Referer:https:/localhost:8081/link?query=xxxxx | 請求資源的完整URI |
User-Agent:Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTML,likeGecko)Chrome/67.0.3396.99Safari/537.36 | 瀏覽器信息 |
Cookie:BAIDUID=FA89F036:FG=1;BD_HOME=1;sugstore=0 | 當(dāng)前域名下的Cookie |
Accept:text/html,image/apng | 代表客戶端希望接受的數(shù)據(jù)類型是html或者是png圖片類型 |
Accept-Encoding:gzip,deflate | 代表客戶端能支持 gzip 和 deflate 格式的壓縮 |
Accept-Language:zh-CN,zh;q=0.9 | 代表客戶端可以支持語言 zh-CN 或者 zh (值得一提的是q(0~1)是優(yōu)先級權(quán)重的意思,不寫默認(rèn)為1,這里 zh-CN 是1, zh 是0.9) |
Connection:keep-alive | 告訴服務(wù)器,客戶端需要的 tcp 連接是一個(gè)長連接 |
3.3 Response Header
參考文章:[《HTTP常用頭部信息》] (https://www.cnblogs.com/amiezhang/p/9389840.html)
舉例:
| Response Header | 描述 |
|---|---|
HTTP/1.1200OK | 響應(yīng)狀態(tài)行 |
Date:Mon,30Jul201802:50:55GMT | 服務(wù)端發(fā)送資源時(shí)的服務(wù)器時(shí)間 |
Expires:Wed,31Dec196923:59:59GMT | 較過時(shí)的一種驗(yàn)證緩存的方式,與瀏覽器(客戶端)的時(shí)間比較,超過這個(gè)時(shí)間就不用緩存(不和服務(wù)器進(jìn)行驗(yàn)證),適合版本比較穩(wěn)定的網(wǎng)頁 |
Cache-Control:no-cache | 現(xiàn)在最多使用的控制緩存的方式,會和服務(wù)器進(jìn)行緩存驗(yàn) |
etag:"fb8ba2f80b1d324bb997cbe188f28187-ssl-df" | 一般是Nginx靜態(tài)服務(wù)器發(fā)來的靜態(tài)文件簽名,瀏覽在沒有 “Disabled cache” 情況下,接收到 etag 后,同一個(gè) url 第二次請求就會自動帶上 “If-None-Match” |
Last-Modified:Fri,27Jul201811:04:55GMT | 服務(wù)器發(fā)來的當(dāng)前資源最后一次修改的時(shí)間,下次請求時(shí),如果服務(wù)器上當(dāng)前資源的修改時(shí)間大于這個(gè)時(shí)間,就返回新的資源內(nèi)容 |
Content-Type:text/html;charset=utf-8 | 如果返回是流式的數(shù)據(jù),我們就必須告訴瀏覽器這個(gè)頭,不然瀏覽器會下載這個(gè)頁面,同時(shí)告訴瀏覽器是utf8編碼,否則可能出現(xiàn)亂碼 |
Content-Encoding:gzip | 告訴客戶端,應(yīng)該采用gzip對資源進(jìn)行解碼 |
Connection:keep-alive | 告訴客戶端服務(wù)器的tcp連接也是一個(gè)長連接 |
4. 請列舉常用的 HTTP 方法,并介紹 GET 與 POST 請求之間的區(qū)別
4.1 HTTP Request Method
參考文章:[《HTTP請求方法對照表》] (http://tools.jb51.net/table/httprequestmethod/)
根據(jù) HTTP 標(biāo)準(zhǔn),HTTP 請求可以使用多種請求方法。 HTTP1.0 定義了三種請求方法: GET, POST 和 HEAD方法。 HTTP/1.1 新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
| 序號 | 方法 | 描述 |
|---|---|---|
| 1 | GET | 請求指定的頁面信息,并返回實(shí)體主體。 |
| 2 | HEAD | 類似于get請求,只不過返回的響應(yīng)中沒有具體的內(nèi)容,用于獲取報(bào)頭 |
| 3 | POST | 向指定資源提交數(shù)據(jù)進(jìn)行處理請求(例如提交表單或者上傳文件)。數(shù)據(jù)被包含在請求體中。POST請求可能會導(dǎo)致新的資源的建立和/或已有資源的修改。 |
| 4 | PUT | 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容。 |
| 5 | DELETE | 請求服務(wù)器刪除指定的頁面。 |
| 6 | CONNECT | HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器。 |
| 7 | OPTIONS | 允許客戶端查看服務(wù)器的性能。 |
| 8 | TRACE | 回顯服務(wù)器收到的請求,主要用于測試或診斷。 |
| 9 | PATCH | 實(shí)體中包含一個(gè)表,表中說明與該URI所表示的原內(nèi)容的區(qū)別。 |
| 10 | MOVE | 請求服務(wù)器將指定的頁面移至另一個(gè)網(wǎng)絡(luò)地址。 |
| 11 | COPY | 請求服務(wù)器將指定的頁面拷貝至另一個(gè)網(wǎng)絡(luò)地址。 |
| 12 | LINK | 請求服務(wù)器建立鏈接關(guān)系。 |
| 13 | UNLINK | 斷開鏈接關(guān)系。 |
| 14 | WRAPPED | 允許客戶端發(fā)送經(jīng)過封裝的請求。 |
| 15 | Extension-mothed | 在不改動協(xié)議的前提下,可增加另外的方法。 |
4.2 GET 與 POST 請求之間的區(qū)別
| 區(qū)別內(nèi)容 | GET | POST |
|---|---|---|
| 點(diǎn)擊返回/刷新按鈕 | 沒有影響 | 數(shù)據(jù)會重新發(fā)送(瀏覽器將會提示“數(shù)據(jù)被重新提交”) |
| 添加書簽 | 可以 | 不可以 |
| 緩存 | 可以 | 不可以 |
| 編碼類型(Encoding type) | application/x-www-form-rulencoded | application/x-www-form-rulencoded?or?multipart/form-data?請為二進(jìn)制數(shù)據(jù)使用?multipart?編碼 |
| 歷史記錄 | 有 | 沒有 |
| 長度限制 | 有 | 沒有 |
| 數(shù)據(jù)類型限制 | 只允許 ASCLll 字符類型 | 沒有限制,允許二進(jìn)制數(shù)據(jù) |
| 安全性 | 查詢字符串會顯示在地址欄的 URL 上,不安全,請不要使用 GET 請求提交敏感數(shù)據(jù) | 因?yàn)閿?shù)據(jù)不會顯示在地址欄中,也不會緩存下來或保存在瀏覽記錄中,所以 POST 請求比 GET 請求安全,但也不是最安全的方式,如需要傳送敏感數(shù)據(jù),請使用數(shù)據(jù)加密。 |
| 可見性 | 查詢字符串在地址欄的 URL 中可見 | 查詢字符串在地址欄的 URL 中不可見 |
5. 請分別介紹 Cookie 和 Session 的作用及它們之間的區(qū)別
參考文章: [《3分鐘搞懂Cookie與Session》] (https://juejin.im/post/5cbf0749e51d456e781f2023)
5.1 Cookie簡單介紹
Cookie是存儲在用戶本地計(jì)算機(jī)上,用于保存一些用戶操作的歷史信息,當(dāng)用戶再次訪問我們的服務(wù)器的時(shí)候,瀏覽器通過HTTP協(xié)議,將他們本地的Cookie內(nèi)容也發(fā)到咱們服務(wù)器上,從而完成驗(yàn)證。

Cookie?是存儲在瀏覽器客戶的一小片數(shù)據(jù);Cookie?可以同時(shí)被前臺與后臺操作;Cookie?可以跨頁面存?。?/span>Cookie?是不可以跨服務(wù)器訪問的;Cookie?有限制; 每個(gè)瀏覽器存儲的個(gè)數(shù)不能超過300個(gè),每個(gè)服務(wù)器不能超過20個(gè),數(shù)據(jù)量不能超過4K;Cookie?是有生命周期的,默認(rèn)與瀏覽器相同,如果進(jìn)程退出,cookie會被銷毀
5.2 Session
Session 存儲在我們的服務(wù)器上,就是在我們的服務(wù)器上保存用戶的操作信息。
當(dāng)用戶訪問我們的網(wǎng)站時(shí),我們的服務(wù)器會成一個(gè)?SessionID,然后把?SessionID?存儲起來,再把這個(gè)?SessionID發(fā)給我們的用戶,用戶再次訪問我們的服務(wù)器的時(shí)候,拿著這個(gè)?SessionID就能驗(yàn)證了,當(dāng)這個(gè)ID能與我們服務(wù)器上存儲的ID對應(yīng)起來時(shí),我們就可以認(rèn)為是自己人。

seesion?數(shù)據(jù)存儲在服務(wù)器端;每一個(gè)會話分配一個(gè)單獨(dú)的?
session_id;該?
session_id?通過?cookie?傳送到前臺,默認(rèn)的?session_id?名稱是?PHPSESSIONID;前臺只能看到?
Session?的?ID,而不能修改?Session?值;使用?
Session之前需要先開啟會話;Session存儲在?Session數(shù)組?$_SESSION;Session存儲方式比較安全,但是如果?Session數(shù)量過多,會導(dǎo)致服務(wù)器性能下降;
5.3 兩者區(qū)別
| Cookie | session | |
|---|---|---|
| 定義 | 瀏覽器保存用戶信息的文件,存儲的數(shù)量和字符數(shù)都有限制 | 服務(wù)器把?sessionID?和用戶信息、用戶操作,記錄在服務(wù)器上,這些記錄就稱為?session |
| 相同點(diǎn) | 都是為了存儲用戶相關(guān)的信息 | |
| 存儲 | 客戶端 | 服務(wù)器 |
| 安全性 | 安全性不高,任何人都能直接查看 | 安全性高 |
5.4 兩者結(jié)合使用
存儲在服務(wù)端:通過?
cookie存儲一個(gè)?session_id,然后具體的數(shù)據(jù)則是保存在?session中。如果用戶已經(jīng)登錄,則服務(wù)器會在?cookie中保存一個(gè)?session_id,下次再次請求的時(shí)候,會把該?session_id攜帶上來,服務(wù)器根據(jù)?session_id在?session庫中獲取用戶的?session數(shù)據(jù)。就能知道該用戶到底是誰,以及之前保存的一些狀態(tài)信息。這種專業(yè)術(shù)語叫做?server side session。將?
session數(shù)據(jù)加密,然后存儲在?cookie中。這種專業(yè)術(shù)語叫做?client side session。
6. 請介紹 HTTP 請求報(bào)文與響應(yīng)報(bào)文格式
6.1 請求報(bào)文

請求報(bào)文由請求行、請求頭部和請求正文組成:
請求行
格式為:
請求方法+空格+ URL +空格+協(xié)議版本+回車符+換行符
例如:
GET www.baidu.com HTTP/1.1
常見的請求方法有:GET,HEAD,PUT,POST,TRACE,OPTIONS,DELETE以及擴(kuò)展方法。
請求頭部
格式為:
頭部字段名+冒號(:)+值+回車符+換行符
請求頭部為請求報(bào)文添加了一些附加信息,由“名/值”對組成,每行一對,名和值之間使用冒號分隔。
并且,在請求頭部的最后會有一個(gè)空行,表示請求頭部結(jié)束,這一行必不可少。
典型的請求頭部有:
| 請求頭部 | 說明 |
|---|---|
| Host | 接受請求的服務(wù)器地址,可以是IP:端口號,也可以是域名 |
| User-Agent | 發(fā)送請求的應(yīng)用程序名稱 |
| Connection | 指定與連接相關(guān)的屬性,如Connection:Keep-Alive |
| Accept-Charset | 通知服務(wù)端可以發(fā)送的編碼格式 |
| Accept-Encoding | 通知服務(wù)端可以發(fā)送的數(shù)據(jù)壓縮格式 |
| Accept-Language | 通知服務(wù)端可以發(fā)送的語言 |
| |
一般使用在?POST?方法中,?GET?方法不存在請求正文。 | |
POST?方法適用于需要客戶填寫表單的場合。與請求數(shù)據(jù)相關(guān)的最常使用的請求頭是?Content-Type?和?Content-Length?。 |
6.2 響應(yīng)報(bào)文

響應(yīng)報(bào)文由狀態(tài)行、響應(yīng)頭部和響應(yīng)正文組成:
狀態(tài)行
格式為:
協(xié)議版本+空格+狀態(tài)碼+空格+狀態(tài)碼描述+回車符+換行符
狀態(tài)碼劃分:
100?199的狀態(tài)碼是 HTTP / 1.1 向協(xié)議中引入了信息性狀態(tài)碼;
200?299的狀態(tài)碼表示成功;
300?399的狀態(tài)碼指資源重定向;
400?499的狀態(tài)碼指客戶端請求出錯(cuò);
500?599的狀態(tài)碼指服務(wù)端出錯(cuò);
常見的狀態(tài)碼:
| 狀態(tài)碼 | 說明 |
|---|---|
| 200 | 響應(yīng)成功 |
| 302 | 跳轉(zhuǎn),跳轉(zhuǎn)地址通過響應(yīng)頭中的位置屬性指定(JSP中Forward和Redirect之間的區(qū)別) |
| 400 | 客戶端請求有語法錯(cuò)誤,不能被服務(wù)器識別 |
| 403 | 服務(wù)器接收到請求,但是拒絕提供服務(wù)(認(rèn)證失敗) |
| 404 | 請求資源不存在 |
| 500 | 服務(wù)器內(nèi)部錯(cuò)誤 |
| |
| 格式為: |
頭部字段名+冒號(:)+值+回車符+換行符
常見響應(yīng)頭部:
| 響應(yīng)頭部 | 說明 |
|---|---|
Server | 服務(wù)器應(yīng)用程序軟件的名稱和版本 |
Content-Type | 響應(yīng)正文的類型(是圖片還是二進(jìn)制字符串) |
Content-Length | 響應(yīng)正文長度 |
Content-Charset | 響應(yīng)正文使用的編碼 |
Content-Encoding | 響應(yīng)正文使用的數(shù)據(jù)壓縮格式 |
Content-Language | 響應(yīng)正文使用的語言 |
7. HTTP/1.1 有什么優(yōu)缺點(diǎn)
參考文章:[《HTTP/1.0 HTTP/1.1 HTTP/2.0 主要特性對比》] (https://segmentfault.com/a/1190000013028798?utm_source=tag-newest)
對于?HTTP/1.1,不僅繼承了?HTTP1.0簡單的特點(diǎn),還克服了諸多?HTTP1.0性能上的問題。
7.1 HTTP/1.1 優(yōu)點(diǎn)
增加持久性連接
也就是多個(gè)請求和響應(yīng)可以利用同一個(gè) TCP 連接,而不是每一次請求響應(yīng)都要新建一個(gè)TCP連接,減少了建立和關(guān)閉連接的消耗和延遲。
Connection: keep-alive
增加管道機(jī)制
增加了管道機(jī)制,請求可以同時(shí)發(fā)出,但是響應(yīng)必須按照請求發(fā)出的順序依次返回,性能在一定程度上得到了改善。

分塊傳輸
在 HTTP/1.1 版本中,可以不必等待數(shù)據(jù)完全處理完畢再返回,服務(wù)器產(chǎn)生部分?jǐn)?shù)據(jù),那么就發(fā)送部分?jǐn)?shù)據(jù),很明此種方式更加優(yōu)秀一些,可以節(jié)省很多等待時(shí)間。
增加?
host?字段
使得一個(gè)服務(wù)器能夠用來創(chuàng)建多個(gè) Web 站點(diǎn)。
錯(cuò)誤提示
HTTP/1.1 引入了一個(gè)?Warning?頭域,增加對錯(cuò)誤或警告信息的描述,此外,在 HTTP/1.1 中新增了24個(gè)狀態(tài)響應(yīng)碼(100,101,203,205,206,301,305… )。
帶寬優(yōu)化
HTTP/1.1 中在請求消息中引入了?range頭域,它允許只請求資源的某個(gè)部分。
在響應(yīng)消息中?Content-Range頭域聲明了返回的這部分對象的偏移值和長度。如果服務(wù)器相應(yīng)地返回了對象所請求范圍的內(nèi)容,則響應(yīng)碼為?206(PartialContent),它可以防止?Cache將響應(yīng)誤以為是完整的一個(gè)對象,HTTP/1.1 加入了一個(gè)新的狀態(tài)碼?100(Continue)。客戶端事先發(fā)送一個(gè)只帶頭域的請求,如果服務(wù)器因?yàn)闄?quán)限拒絕了請求,就回送響應(yīng)碼?401(Unauthorized);如果服務(wù)器接收此請求就回送響應(yīng)碼?100,客戶端就可以繼續(xù)發(fā)送帶實(shí)體的完整請求了。
注意,HTTP/1.0 的客戶端不支持 100 響應(yīng)碼。但可以讓客戶端在請求消息中加入?Expect頭域,并將它的值設(shè)置為?100-continue。
7.2 HTTP/1.1 缺點(diǎn)
隊(duì)頭阻塞
此版本的網(wǎng)絡(luò)延遲問題主要由于隊(duì)頭堵塞導(dǎo)致,雖然通過持久性連接得到改善,但是每一個(gè)請求的響應(yīng)依然需要按照順序排隊(duì),如果前面的響應(yīng)處理較為耗費(fèi)時(shí)間,那么同樣非常耗費(fèi)性能。
技術(shù)不成熟
還有此版本雖然引進(jìn)了管道機(jī)制,但是當(dāng)前存在諸多問題,且默認(rèn)處于關(guān)閉狀態(tài)。
浪費(fèi)資源
http/1.1 請求會攜帶大量冗余的頭信息,浪費(fèi)了很多寬帶資源。
8. 相比 HTTP/1.1,HTTP/2.0 有哪些新特性
參考文章:[《HTTP1.0 HTTP/1.1 HTTP2.0 主要特性對比》] (https://segmentfault.com/a/1190000013028798?utm_source=tag-newest)
二進(jìn)制分幀
在應(yīng)用層(HTTP/2.0)和傳輸層(TCP or UDP)之間增加一個(gè)二進(jìn)制分幀層,從而突破 HTTP1.1 的性能限制,改進(jìn)傳輸性能,實(shí)現(xiàn)低延遲和高吞吐量。

可見,雖然 HTTP/2.0 的協(xié)議和 HTTP1.x 協(xié)議之間的規(guī)范完全不同了,但是實(shí)際上 HTTP/2.0并 沒有改變 HTTP1.x 的語義。
簡單來說,HTTP/2.0 只是把原來 HTTP1.x 的?header?和?body?部分用?frame?重新封裝了一層而已。
多路復(fù)用(連接共享)
允許同時(shí)通過單一的 HTTP/2 連接發(fā)起多重的請求-響應(yīng)消息,這個(gè)強(qiáng)大的功能則是基于“二進(jìn)制分幀”的特性。

從圖中可見,所有的 HTTP/2.0 通信都在一個(gè) TCP 連接上完成,這個(gè)連接可以承載任意數(shù)量的雙向數(shù)據(jù)流。
每個(gè)數(shù)據(jù)流以消息的形式發(fā)送,而消息由一或多個(gè)幀組成。這些幀可以亂序發(fā)送,然后再根據(jù)每個(gè)幀頭部的流標(biāo)識符(?stream id)重新組裝。
首部壓縮
HTTP1.1 不支持?header?數(shù)據(jù)的壓縮,HTTP/2.0 使用?HPACK?算法對?header?的數(shù)據(jù)進(jìn)行壓縮,這樣數(shù)據(jù)體積小了,在網(wǎng)絡(luò)上傳輸就會更快。高效的壓縮算法可以很大的壓縮?header?,減少發(fā)送包的數(shù)量從而降低延遲。
服務(wù)器推送
在 HTTP/2 中,服務(wù)器可以對客戶端的一個(gè)請求發(fā)送多個(gè)響應(yīng),即服務(wù)器可以額外的向客戶端推送資源,而無需客戶端明確的請求。
9. 請簡述 HTTPS 工作原理
9.1 HTTPS 簡介
參考文章:[《深入淺出講解HTTPS工作原理》] (developer.51cto.com/art/201812/589283.htm)
HTTPS 并非是應(yīng)用層的一種新協(xié)議。只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)協(xié)議代替而已。
通常,HTTP 直接和 TCP 通信。當(dāng)使用 SSL 時(shí),則演變成先和 SSL 通信,再由 SSL 和 TCP 通信了。簡言之,所謂 HTTPS,其實(shí)就是身披 SSL 協(xié)議這層外殼的 HTTP。

在采用 SSL 后,HTTP 就擁有了 HTTPS 的加密、證書和完整性保護(hù)這些功能。也就是說HTTP 加上加密處理和認(rèn)證以及完整性保護(hù)后即是 HTTPS。

HTTPS 協(xié)議的主要功能基本都依賴于 TLS/SSL 協(xié)議,TLS/SSL 的功能實(shí)現(xiàn)主要依賴于三類基本算法:散列函數(shù)?、對稱加密和非對稱加密,其利用非對稱加密實(shí)現(xiàn)身份認(rèn)證和密鑰協(xié)商,對稱加密算法采用協(xié)商的密鑰對數(shù)據(jù)加密,基于散列函數(shù)驗(yàn)證信息的完整性。

9.2 HTTPS 工作原理
HTTPS 其實(shí)是有兩部分組成:HTTP?+?SSL / TLS,也就是在 HTTP 上又加了一層處理加密信息的模塊。服務(wù)端和客戶端的信息傳輸都會通過 TLS 進(jìn)行加密,所以傳輸?shù)臄?shù)據(jù)都是加密后的數(shù)據(jù)。

客戶端發(fā)起HTTPS請求
瀏覽器里面輸入一個(gè)HTTPS網(wǎng)址,然后連接到服務(wù)端的443端口上。注意這個(gè)過程中客戶端會發(fā)送一個(gè)密文族給服務(wù)端,密文族是瀏覽器所支持的加密算法的清單。
服務(wù)端配置
采用HTTPS協(xié)議的服務(wù)器必須要有一套數(shù)字證書,可以自己制作,也可以向組織申請。區(qū)別就是自己頒發(fā)的證書需要客戶端驗(yàn)證通過才可以繼續(xù)訪問,而使用受信任的公司申請的證書則不會彈出提示頁面。
這套證書其實(shí)就是一對公鑰和私鑰,可以這么理解,公鑰就是一把鎖頭,私鑰就是這把鎖的鑰匙,鎖頭可以給別人對某個(gè)東西進(jìn)行加鎖,但是加鎖完畢之后,只有持有這把鎖的鑰匙才可以解鎖看到加鎖的內(nèi)容。
傳送證書
這個(gè)證書其實(shí)就是公鑰,只是包含了很多信息,如證書的頒發(fā)機(jī)構(gòu)、過期時(shí)間等等。
客戶端解析證書
這部分工作是由客戶端的TLS來完成的,首先會驗(yàn)證公鑰是否有效,如頒發(fā)機(jī)構(gòu)、過期時(shí)間等等,如果發(fā)現(xiàn)異常則會彈出一個(gè)警告框,提示證書存在問題。如果證書沒有問題,那么就生成一個(gè)隨機(jī)值,然后用證書對該隨機(jī)值進(jìn)行加密。
注意一下上面提到的"發(fā)現(xiàn)異常"。證書中會包含數(shù)字簽名,該數(shù)字簽名是加密過的,是用頒發(fā)機(jī)構(gòu)的私鑰對本證書的公鑰、名稱及其他信息做hash散列加密而生成的??蛻舳藶g覽器會首先找到該證書的根證書頒發(fā)機(jī)構(gòu),如果有,則用該根證書的公鑰解密服務(wù)器下發(fā)的證書,如果不能正常解密,則就是"發(fā)現(xiàn)異常",說明該證書是偽造的。
傳送加密信息
這部分傳送的是用證書加密后的隨機(jī)值,目的就是讓服務(wù)端得到這個(gè)隨機(jī)值,然后客戶端和服務(wù)端的通信就可以通過這個(gè)隨機(jī)值來進(jìn)行加密和解密了。
服務(wù)端解密信息
服務(wù)端用私鑰解密后,得到了客戶端傳過來的隨機(jī)值,至此一個(gè)非對稱加密的過程結(jié)束,看到TLS利用非對稱加密實(shí)現(xiàn)了身份認(rèn)證和密鑰協(xié)商。然后把內(nèi)容通過該值進(jìn)行對稱加密。
傳輸加密后的信息
這部分是服務(wù)端用隨機(jī)值加密后的信息,可以在客戶端被還原。
客戶端解密信息
客戶端用之前生成的隨機(jī)值解密服務(wù)端傳送過來的信息,于是獲取了解密后的內(nèi)容,至此一個(gè)對稱加密的過程結(jié)束,看到對稱加密是用于對服務(wù)器待傳送給客戶端的數(shù)據(jù)進(jìn)行加密用的。整個(gè)過程即使第三方監(jiān)聽了數(shù)據(jù),也束手無策。
10. HTTP 和 HTTPS 的共同點(diǎn)和區(qū)別
https 協(xié)議需要到 ca 申請證書,一般免費(fèi)證書較少,因而需要一定費(fèi)用。
http 是超文本傳輸協(xié)議,信息是明文傳輸, https 則是具有安全性的ssl加密傳輸協(xié)議。
http 和 https 使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
http 的連接很簡單,是無狀態(tài)的; HTTPS 協(xié)議是由 SSL+HTTP 協(xié)議構(gòu)建的可進(jìn)行加密傳輸、身份認(rèn)證的網(wǎng)絡(luò)協(xié)議,比 http 協(xié)議安全。
11. 什么是跨域,如何解決跨域
參考文章:[《前端常見跨域解決方案(全)》] (https://segmentfault.com/a/1190000011145364)
11.1 什么是跨域
跨域,指的是瀏覽器不能執(zhí)行其他網(wǎng)站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制。
什么是同源策略?
同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到 XSS 、 CSFR 等攻擊。所謂同源是指"協(xié)議+域名+端口"三者相同,即便兩個(gè)不同的域名指向同一個(gè)ip地址,也非同源。
同源策略限制了以下行為:
Cookie、?LocalStorage?和?IndexDB?無法讀取DOM?和?JS對象無法獲取Ajax請求發(fā)送不出去
常見跨域場景:
所謂的同源是指:域名、協(xié)議、端口均為相同。
http://www.a.cn/index.html?調(diào)用?http://www.a.cn/server.php?非跨域。http://www.a.cn/index.html?調(diào)用?http://www.b.cn/server.php?跨域,主域不同。http://abc.a.cn/index.html?調(diào)用?http://def.b.cn/server.php?跨域,子域名不同。http://www.a.cn:8080/index.html?調(diào)用?http://www.a.cn/server.php?跨域,端口不同。https://www.a.cn/index.html?調(diào)用?http://www.a.cn/server.php?跨域,協(xié)議不同。localhost?調(diào)用?127.0.0.1?跨域。
11.2 解決跨域
jsonp?跨域document.domain?+?iframe?跨域window.name?+?iframe?跨域location.hash?+?iframe?跨域postMessage?跨域跨域資源共享?
CORSwithCredentials?屬性WebSocket?協(xié)議跨域node?代理跨域nginx?代理跨域
具體每一種解決方法,可以參考:[《前端常見跨域解決方案(全)》] (https://segmentfault.com/a/1190000011145364)
12. HTTP 中與緩存相關(guān)的頭部有哪些,它們有什么區(qū)別
| 頭部 | 優(yōu)勢和特點(diǎn) | 劣勢和問題 |
|---|---|---|
Expires | 1、?HTTP1.0?產(chǎn)物,可以在?HTTP1.0和?1.1中使用,簡單易用。2、以時(shí)刻標(biāo)識失效時(shí)間。 | 1、時(shí)間是由服務(wù)器發(fā)送的(?UTC),如果服務(wù)器時(shí)間和客戶端時(shí)間存在不一致,可能會出現(xiàn)問題。2、存在版本問題,到期之前的修改客戶端是不可知的。 |
Cache-Control | 1、?HTTP1.1?產(chǎn)物,以時(shí)間間隔標(biāo)識失效時(shí)間,解決了?Expires服務(wù)器和客戶端相對時(shí)間的問題。2、比?Expires多了很多選項(xiàng)設(shè)置。 | 1、?HTTP1.1才有的內(nèi)容,不適用于?HTTP1.0。2、存在版本問題,到期之前的修改客戶端是不可知的。 |
Last-Modified | 1、不存在版本問題,每次請求都會去服務(wù)器進(jìn)行校驗(yàn)。服務(wù)器對比最后修改時(shí)間如果相同則返回304,不同返回200以及資源內(nèi)容。 | 1、只要資源修改,無論內(nèi)容是否發(fā)生實(shí)質(zhì)性的變化,都會將該資源返回客戶端。例如周期性重寫,這種情況下該資源包含的數(shù)據(jù)實(shí)際上一樣的。2、以時(shí)刻作為標(biāo)識,無法識別一秒內(nèi)進(jìn)行多次修改的情況。3、某些服務(wù)器不能精確的得到文件的最后修改時(shí)間。 |
ETag | 1、可以更加精確的判斷資源是否被修改,可以識別一秒內(nèi)多次修改的情況。2、不存在版本問題,每次請求都回去服務(wù)器進(jìn)行校驗(yàn)。 | 1、計(jì)算?ETag值需要性能損耗。2、分布式服務(wù)器存儲的情況下,計(jì)算?ETag的算法如果不一樣,會導(dǎo)致瀏覽器從一臺服務(wù)器上獲得頁面內(nèi)容后到另外一臺服務(wù)器上進(jìn)行驗(yàn)證時(shí)發(fā)現(xiàn)?ETag不匹配的情況。 |
13. 分別介紹強(qiáng)緩存和協(xié)商緩存
瀏覽器緩存主要分為強(qiáng)緩存(也稱本地緩存)和協(xié)商緩存(也稱弱緩存)。
13.1 強(qiáng)緩存
強(qiáng)緩存是利用?http?頭中的?Expires?和?Cache-Control?兩個(gè)字段來控制的,用來表示資源的緩存時(shí)間。
強(qiáng)緩存中,普通刷新會忽略它,但不會清除它,需要強(qiáng)制刷新。瀏覽器強(qiáng)制刷新,請求會帶上?Cache-Control:no-cache?和?Pragma:no-cache。
通常,強(qiáng)緩存不會向服務(wù)器發(fā)送請求,直接從緩存中讀取資源,在chrome控制臺的network選項(xiàng)中可以看到該請求返回200的狀態(tài)碼。分為?fromdisk cache?和?frommemory cache。
fromdisk cache?:一般非腳本會存在內(nèi)存當(dāng)中,如css,html等frommemory cache?:資源在內(nèi)存當(dāng)中,一般腳本、字體、圖片會存在內(nèi)存當(dāng)
有緩存命中和緩存未命中狀態(tài):


13.2 協(xié)商緩存
協(xié)商緩存就是由服務(wù)器來確定緩存資源是否可用,所以客戶端與服務(wù)器端要通過某種標(biāo)識來進(jìn)行通信,從而讓服務(wù)器判斷請求資源是否可以緩存訪問。
普通刷新會啟用弱緩存,忽略強(qiáng)緩存。只有在地址欄或收藏夾輸入網(wǎng)址、通過鏈接引用資源等情況下,瀏覽器才會啟用強(qiáng)緩存,這也是為什么有時(shí)候我們更新一張圖片、一個(gè)js文件,頁面內(nèi)容依然是舊的,但是直接瀏覽器訪問那個(gè)圖片或文件,看到的內(nèi)容卻是新的。
這個(gè)主要涉及到兩組?header?字段:?Etag?和?If-None-Match、?Last-Modified和?If-Modified-Since。
向服務(wù)器發(fā)送請求,服務(wù)器會根據(jù)這個(gè)請求的request header的一些參數(shù)來判斷是否命中協(xié)商緩存。
有緩存命中和緩存未命中狀態(tài):


13.3 流程
瀏覽器第一次發(fā)起請求,本地有緩存情況: 在瀏覽器第一次發(fā)起請求時(shí),本地?zé)o緩存,向web服務(wù)器發(fā)送請求,服務(wù)器起端響應(yīng)請求,瀏覽器端緩存。過程如下:

在第一次請求時(shí),服務(wù)器會將頁面最后修改時(shí)間通過?Last-Modified標(biāo)識由服務(wù)器發(fā)送給客戶端,客戶端記錄修改時(shí)間;服務(wù)器還會生成一個(gè)Etag,并發(fā)送給客戶端。
瀏覽器后續(xù)再次進(jìn)行請求時(shí):

14. 請簡單介紹一下 LRU (Least recently used)算法
參考文章:[《LRU算法》] (https://www.jianshu.com/p/d533d8a66795)
14.1 原理
LRU(Least recently used,最近最少使用)算法根據(jù)數(shù)據(jù)的歷史訪問記錄來進(jìn)行淘汰數(shù)據(jù),其核心思想是“如果數(shù)據(jù)最近被訪問過,那么將來被訪問的幾率也更高”。

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

14.2 實(shí)現(xiàn)
最常見的實(shí)現(xiàn)是使用一個(gè)鏈表保存緩存數(shù)據(jù),詳細(xì)算法實(shí)現(xiàn)如下:
新數(shù)據(jù)插入到鏈表頭部;
每當(dāng)緩存命中(即緩存數(shù)據(jù)被訪問),則將數(shù)據(jù)移到鏈表頭部;
當(dāng)鏈表滿的時(shí)候,將鏈表尾部的數(shù)據(jù)丟棄。
14.3 分析
命中率
當(dāng)存在熱點(diǎn)數(shù)據(jù)時(shí),LRU的效率很好,但偶發(fā)性的、周期性的批量操作會導(dǎo)致LRU命中率急劇下降,緩存污染情況比較嚴(yán)重。
復(fù)雜度
實(shí)現(xiàn)簡單。
代價(jià)
命中時(shí)需要遍歷鏈表,找到命中的數(shù)據(jù)塊索引,然后需要將數(shù)據(jù)移到頭部。
結(jié)語
本文主要復(fù)習(xí)了 HTTP/HTTPS 的一些基礎(chǔ)知識,還有 HTTP 的其他版本的知識,對于面試也好,知識沉淀也好,這些也是我們作為開發(fā)者必須懂的。
作為一名前端開發(fā)者,說實(shí)話對 HTTP/HTTPS 了解還是太少,可能和平常工作內(nèi)容有關(guān)。
小獅子有話說
你好,我是 Chocolate,一個(gè)獅子座的前端攻城獅,希望成為優(yōu)秀的前端博主,每周都會更新文章,與你一起變優(yōu)秀~
- 關(guān)注
小獅子前端,回復(fù)【小獅子】獲取為大家整理好的文章、資源合集 - 我的博客地址:
yangchaoyi.vip歡迎收藏,可在博客留言板留下你的足跡,一起交流~ - 覺得文章不錯(cuò),【
點(diǎn)贊】【在看】支持一波 ??ヽ(°▽°)ノ?
叮咚~ 可以給小獅子加
星標(biāo),便于查找。感謝加入小獅子前端,最好的我們最美的遇見,我們下期再見~
