大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信?ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。已進行四個月了,很多小伙伴表示收獲頗豐。
想學源碼,極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。同時推薦參與源碼共讀活動。
本文來自@Fishing 讀者投稿,原文鏈接:https://juejin.cn/post/7036608827252277279
一、什么是URI?
URI, 全稱為(Uniform Resource Identifier), 也就是統一資源標識符。它并不是我們常說的網址URL
, 實際上URI
= URN
+URL
。
1.URI的結構
它主要由以下幾個結構組成:
scheme 表示協議名,比如http
,https
等
user:passwd@ 表示登錄主機時的用戶信息
host 主機名
port 端口
path 資源路徑
query 表示查詢參數,通常以?
開頭多個值之間以&
連接
fragment 頁面資源錨點位置,常見為:https://www.baidu.com/path/index.html#name
2.URI編碼
URI
只能使用ASCII
, ASCII
之外的字符是不支持顯示的。此外,URI
引入了編碼機制,將所有非ASCII
碼字符和界定符轉為十六進制字節值,然后在前面加個%
,例如:空格被轉義成了%20
。
二、HTTP狀態碼你能記住哪些?
HTTP狀態碼總體分為五類:
整體范圍 | 已定義范圍 | 含義 |
---|---|---|
100~199 | 100~101 | 信息提示 |
200~299 | 200~206 | 成功 |
300~399 | 300~305 | 重定向 |
400~499 | 400~415 | 客戶端錯誤 |
500~599 | 500~505 | 服務器錯誤 |
接下來詳細看下每個狀態碼的含義:
1xx相關
100
請求中間狀態,客戶端需要繼續下一步請求。
101
協議切換。例如當HTTP請求升級到websocket服務的時候,如果服務端同意升級,則會返回101狀態碼。
2xx相關
200
請求成功。請求中最常見的狀態碼,也是開發最喜歡的狀態,表示請求一切正常。
201
成功請求并創建了新的資源。
202
服務端已接受請求,但未完成處理。
204
沒有內容。表示只返回head頭信息,主體內容沒返回。
206
表示部分內容。常見于大型文件上傳或下載的過程。
3xx相關
301
永久重定向。將資源永遠的移到新的域名下。
302
臨時重定向。將資源臨時移到新地方,以后還有可能再移回來。
備注:301、302常見于SEO優化或http緩存。以http緩存為例:若永久重定向到新資源,則瀏覽器會緩存新資源,并拋棄老域名的緩存。若臨時重定向則不做緩存優化。
304
常見于http緩存。例如 max-age
時間過期,命中協商緩存的時候,瀏覽器會攜帶相關信息到服務端,服務器對比信息后發現文件沒更新可以繼續使用的情況下就會返回304狀態碼,意思是告訴客戶端文件可以繼續使用。
305
使用代理。表示當前請求的資源必須通過代理訪問。
307
臨時重定向,與302類似。
4xx相關
400
開發者請求錯誤。比較粗糙的提示,具體錯誤原因不明。
401
要求請求方,也就是用戶需要進行身份認證。
403
服務器拒絕訪問。因法律、敏感詞匯等原因,服務器拒絕客戶端的請求。
404
資源未找到。這個很容易理解,也比較常見,服務端沒有對應的資源內容的時候會返回此狀態碼。
405
請求方法錯誤。比較常見于服務端只支持POST請求,但是開發者用GET方式請求了接口,就會返回這個錯誤。反之亦然。
406
服務端資源因某種原因無法滿足客戶端的請求條件。
407
與401類似,要求代理的身份認證。
408
客戶端發送請求時間超時,服務器沒有時間繼續等待了。
409
服務器處理內容的時候發生了沖突。
410
類似404,表示資源以前可能存在,現在被刪除了。
413
客戶端請求體過大,服務器因無法處理而拒絕。
414
請求的URL地址太長,服務器無法處理。
5xx相關
500
服務器內部錯誤,具體啥錯誤咱也不知道,只知道是出錯了。
501
表示服務器不支持客戶端的請求功能。
502
作為網關或者代理工作的服務器嘗試執行請求時,從遠程服務器接收到了一個無效的響應。
503
服務器內部較忙,暫時無法相應。
504
充當網關或代理的服務器,未及時從遠端服務器獲取請求。
505
服務器不支持請求的HTTP協議的版本,無法完成處理。
三、GET與POST的區別
GET請求會被瀏覽器留下訪問記錄,而POST不會留下記錄;
GET請求參數攜帶在URL后面,不太安全,而POST參數會放到請求體重,適合傳輸敏感數據;
GET只能發送 ASCII 字符,而POST沒限制。
發送數據時機不同。GET請求會一次性將數據發送出去,而POST發送分兩部分,先發送header頭部分,如果服務端相應100狀態碼(繼續),然后再發送body部分。
受URL長度限制,GET傳輸數據較少,而POST傳輸數據量較大,一般默認為不受限制。
從冪等性的角度來說,GET是冪等的(只要參數不變,返回的結果總是相等的),而POST不是。
GET在瀏覽器回退時是無害的,而POST會再次發起請求。
四、COOKIE相關
1.什么是cookie
從本質上來說,cookie就是存儲在客戶端的一小段文本,以鍵值對的方式存儲在瀏覽器里。通常瀏覽器只會分配4KB
的空間給cookie,所以存儲內容較少。通常js可以設置、讀取、刪除cookie,服務端也可以通過Set-Cookie
頭字段對瀏覽器進行Cookie
寫入。若服務端設置屬性為http-only
,客戶端js腳本則無法讀取到Cookie
值。
以下是百度網站的一段Cookie
截圖:
屬性說明:
Name Cookie名稱Value Cookie內容
Domain 可以讀取當前Cookie的有效域名
Path 可以讀取當前Cookie的有效路徑
Expires/Max-Age Cookie有效絕對時間/過期相對時間(Session代表當前會話期間,網頁關閉即失效)
Size Cookie大小
HttpOnly 當前Cookie是否只能通過http獲取,攜帶到服務端,js腳本無法獲取
Secure 是否只能通過https傳輸Cookie
SameParty Cookie安全模式,支持三個值:1、`None`,默認模式,http請求默認會帶上Cookie值。2、`Lax`模式,只能再GET方法中攜帶Cookie。3、`Strict`,嚴格模式,只能在當前域名下訪問Cookie,其他域名均無法訪問。
Priority 優先級,chrome的提案,定義了三種優先級,Low/Medium/High,當cookie數量超出時,低優先級的cookie會被優先清除
2.Cookie的生命周期
我們通常通過Expires
和Max-Age
這兩個屬性來設置Cookie
的過期時間。前者指定過期的具體時間,后者是過期的相對時間。若過期,瀏覽器不會主動刪除Cookie
內容,只是無法被讀取到或者無法發送到服務端。
3.Cookie的作用域
涉及到兩個關鍵詞匯:1、域名(Domain)。2、路徑(Path)。不同域名或路徑下無法相互訪問Cookie
內容,當然頂級域名下的Cookie
在子域名之間是共享的,以百度網站為例:.baidu.com
下的cookie可以共享給子域名訪問,例如www.baidu.com
、tieba.baidu.com
等。根路徑(/
)下的cookie也可以共享給任何子目錄訪問。
4.安全、性能優化相關
Cookie
是以字符串的方式存儲在客戶端,以明文的方式在服務器與客戶端之間傳輸,容易被攔截修改。不論當前請求是否需要Cookie
,請求都會攜帶上當前域名下的所有Cookie
,所以會產生大量不必要的數據,影響服務端性能以及帶寬。可以通過設置Cookie
的Domain
以及Path
適當控制攜帶的數量。
5.其他存儲方式
除了Cookie
存儲之外,現代瀏覽器還支持localStorage
、sessionStorage
存儲,兩者的主要區別在于前者是永久存儲在瀏覽器,后者的生命周期是會話級別的,網頁關閉即消失。還有indexDB
,感興趣的同學可參考阮老師的?瀏覽器數據庫 IndexedDB 入門教程
五、跨域問題
1.為什么會產生跨域
相信現在絕大多數公司采用的都是前后端分離的開發模式,通過Ajax
請求響應數據,當前訪問網頁的URL與接口地址用的不是一個域名。這個時候瀏覽器就會認為是跨域了,存在一定安全隱患。詳細來說就是請求網頁與接口之間只要滿足以下任一條件,即被認為跨域:
1、協議不同
2、域名不同
3、端口號不同
因為瀏覽器遵循同源策略
,當請求與響應不同源的時候,瀏覽器會試圖先發送一個OPTIONS
預請求給服務端,同時會加上Origin
源地址和Host
目標地址,詢問是否允許跨域,也就是看http返回頭字段Access-Control-Allow-Origin
,若是*
表示允許任何請求,也可以是指定的請求源地址。若允許則繼續,否則瀏覽器會中斷后續請求并打印錯誤。注意是被瀏覽器攔截了,請求是到達服務端了。服務端發號施令,控制是否允許跨域,而瀏覽器是實際執行者。
2.常見的跨域解決方案
JSONP
JSONP實現的原理:雖然XMLHttpRequest
對象遵循同源政策,但是script
標簽不一樣,它可以通過 src
填上目標地址從而發出 GET 請求,實現跨域請求并拿到響應。接下來我們封裝一個簡單的JSONP:
let?myJSONP?=?(_url,params,callback)?=>?{let?splitUrl?=?(_url,params)?=>?{let?str?=?'';for(let?key?in?params){str?+=?key+'='+params[key]}return?_url?+?'?'?+?str}return?new?Promise(resolve?=>?{let?_srcipt?=?document.createElement('script');_srcipt.src?=?splitUrl(_url,params);document.body.appendChild(_srcipt);window[callback]?=?res?=>?{resolve(res)//渣男,用完即刪除document.body.removeChild(_srcipt)}})
}
Nginx
讓運維同學在Nginx
中做反向代理,將所有請求中轉一下,讓服務端識別請求,以為是來自同源的請求,予以通過。
比如說現在客戶端的域名為client.com,服務器的域名為server.com,客戶端向服務器發送 Ajax 請求。Nginx
配置方式如下:
server?{listen??443;server_name??client.com;location?/yourApiAddress?{proxy_pass?server.com;}
}
Nginx
在其中相當于跳板機的作用。
CORS
開發同學代碼中CORS
設置允許任何來源即可。個人推薦這種配置,基本上一勞永逸,Nginx
代理是運維同學設置的,經常遇到服務器調整等原因導致跨域反反復復,比較煩人。
其他方式
除此之外就是一些奇淫技巧的跨域解決方案,例如postMessage
、iframe
等等,現實中基本上不會用到。就不建議深入了解了,記個大概即可。
六、HTTP請求方法有哪些
HTTP1.0:GET
、POST
、HEAD
HTTP1.1:PUT
、PATCH
、DELETE
、OPTIONS
、TRACE
、CONNECT
方法 | 描述 |
---|---|
GET | 獲取資源 |
POST | 資源傳輸,通常會修改服務器資源 |
HEAD | 獲得請求頭信息 |
PUT | 更新資源 |
DELETE | 刪除資源 |
PATCH | 對PUT的補充,對已知資源部分更新 |
OPTIONS | 列出請求資源支持的請求方法,用來跨域請求 |
TRACE | 追蹤請求/響應路徑,用于測試或診斷 |
CONNECT | 將連接改為管道方式用于代理服務器 |
七、常見HTTP請求頭有哪些
1.Request Headers
User-Agent 瀏覽器信息,內容包含發出請求的用戶信息。
Cookie 當前域名下所有能讀取到的Cookie
內容,不論服務器是否需要,都會被攜帶。
Accept 瀏覽器可接受的MIME類型。
Accept-Charset 瀏覽器可接受的字符集。
Accept-Encoding 瀏覽器可接受的壓縮編碼方式,常見的壓縮方式有gzip
、br
、Servlet
Accept-Language 瀏覽器能接受的語言。
Content-Length 表示請求消息正文的長度。
Authorization 授權信息,通常出現在對服務器發送的WWW-Authenticate頭的應答中。
Host 客戶端請求域。
If-Modified-Since 對應 response返回值 last-Modified
文件最后修改時間。
If-None-Match 對應 response返回值 Etag
文件唯一標識。
2.Response Headers
Cache-control 詳見下面http緩存一欄,會詳細講
Content-encoding 壓縮編碼方式,對應 Accept-Encoding
Content-Length 表示內容長度。
Content-Type 表示后面的文檔屬于什么MIME類型
Date 當前的GMT時間。
Expires 告訴客戶端緩存的絕對時間(目前基本上已不再使用)
Last-Modified 文件最后編輯時間
Etag 當前文件內容唯一標識,若被重新修改則會有變動。
Server 服務器通過這個頭告訴瀏覽器服務器的類型。
八、TCP三次握手
在介紹三次握手之前,先拋出一個問題:為什么是三次握手,不是兩次或者四次?
首先我們要先理解握手的目的是什么?為了確保雙方的發送、接收能力正常。
就像打電話之前,雙方先“喂喂喂,聽得見嘛”,一個道理。
最開始客戶端處于CLOSED
狀態,服務器處于LISTEN
狀態(隨時等待被撩)。
第一握手: 客戶端首先發送一段
SYN
報文,包含生成的序列號,這個時候客戶端處于發送后等待
狀態。第二次握手: 服務端收到客戶端發送的
SYN
報文后,將序列號+1
后作為ACk
應答碼返回給客戶端,一并返回的包括服務端生成的序列號。這個時候服務端就處于半連接
狀態,服務端也能確認了客戶端的發送能力正常
,自己的發送能力
、接收能力
正常,唯獨不知道客戶端的接收能力是否正常。所以說二次握手并不能滿足實際需要。第三次握手: 客戶端接收到服務端返回的
ACK
以及序列號后,將序列號+1
作為ACK
碼再返回給服務端。這個時候客戶端就能確認自己的發送
、接收
能力正常,服務端的發送
、接收
能力也正常。服務端接收到ACK
碼之后,將之前的半連接轉換成全連接,也就完成了握手連接。
所以,三次握手正好確認雙方的發送
、接收
能力正常了,再多一次可以嘛?其實也可以的,只是無用,白白浪費了而已,所以三次足以。
備注:三次握手過程中,前兩次不可攜帶數據,第三次握手可以攜帶數據。因為前兩次若能攜帶數據的話,攻擊者會利用這個缺陷發送大量數據給服務端,而故意忽略第三次,從而導致服務端產生大量半連接
狀態會話,同時服務器要耗費更多內存去處理數據,半連接
多了,達到一定數量后影響正常連接
,導致丟包等事件發生,故而產生SYN
攻擊。第三次握手是可以攜帶數據的,因為第三次握手的時候,已經建立了正常連接,互相信任了,這個時候處理數據也無可厚非。
九、TCP四次揮手
有握手的過程,必然就會有分手的過程嘛。四次的過程是這樣的:
第一次揮手: 客戶端要斷開連接,向服務端發送
FIN
報文,其中會包含客戶端生成的序列號。這個時候客戶端處于FIN-WAIT-1
狀態,也就是說這個時候客戶端處于只能接收、不會再發送的狀態。第二次揮手: 服務端回應客戶端狀態。這個時候服務端也不在接收來自客戶端的數據,處于
CLOSED-WAIT
狀態,但是還有未處理完的數據要繼續處理。客戶端收到服務端反饋后變成FIN-WAIT2
狀態。第三次揮手: 服務端處理完最后發送的數據后,再想客戶端發送
FIN
,自己進入LAST-ACK
狀態。第四次揮手: 客戶端收到服務端發來的
FIN
后,自己變成了TIME-WAIT
狀態,然后發送ACK
給服務端。
備注:第三次揮手后,服務端會間隔一定時間發送報文給客戶端,確保客戶端收到報文。只有當收到客戶端第四次揮手返回的信息,才不會發送。所以第四次揮手后,客戶端需要等待足夠長的時間(2MSL
),也就是報文最大生存時間,來確保沒有再收到服務端返回的信息,只要沒收到信息,客戶端就能確保服務端收到第四次握手信息了,服務端也確保第三次握手也是成功的了。
十、HTTP緩存
緩存是性能優化中非常重要的一環,瀏覽器的緩存機制對開發也是非常重要的知識點。接下來以三個部分來把瀏覽器的緩存機制說清楚:
強緩存
協商緩存
緩存位置
1.什么是強緩存、協商緩存
關于什么時候命中強緩存
,什么時候命中協商緩存
,主要依賴于http
返回頭信息里的Cache-Control
返回字段進行控制。
什么情況下命中強緩存?以常見的max-age
為例:若max-age=5356800
,則意思是說瀏覽器在首次請求這個文件的時候,可以在本地磁盤中保存這個文件5356800秒
,從首次加載時間開始以后的這些時間內,若再次請求這個文件,瀏覽器可以不發起http
請求,而直接使用緩存中的內容即可,這樣不僅節省了服務器負擔,也提升網站用戶體驗。
什么情況下命中協商緩存?仍然以常見的max-age
為例:若max-age=5356800
,距離第一次請求文件已經過去了5356800秒
,當用戶再次需要這個資源的時候,瀏覽器就會拿之前這個文件返回的Etag
以及Last-Modified
,分別命名為If-None-Match
和If-Modified-Since
作為請求參數傳給服務端,服務端與現有文件進行匹配,若文件已更新,則返回200
狀態碼,同時返回最新文件給客戶端。若文件未更新,則返回304
狀態碼,告訴客戶端緩存有效,可以繼續使用。
2.緩存位置
關于文件緩存位置,可通過Chrome
開發面板中,Network
欄目下每個文件后面有一個Size
屬性查看
首次請求,會顯示當前文件大小,例如
xxkB
。在網頁未關閉之前,再次請求,會從內存中取出文件,顯示
(memory cache)
。關閉網頁再次請求的時候,若命中強緩存,會從磁盤中取出,顯示
(disk cache)
。
3.Cache-Control有哪些字段
public 公共的。表示任何人都可以緩存,包括瀏覽器、代理服務器等。
private 私有的。表示只允許單個用戶緩存,不能作為共享緩存。
no-cache 本地可以緩存,但每次都需要與服務端協商,即每次都命中協商緩存。
no-store 不適用任何緩存。
max-age=xxx 設置緩存最大周期(單位秒),超過這個相對時間被認為是過期,需要與服務端協商是否還可繼續使用。與Expires
不同,因為它是絕對時間,目前基本上已被廢棄,因為若服務器時間與客戶端時間相差較大的情況下,會產生一些異常問題。
s-maxage=xxx 設置代理服務器緩存文件過期相對時間,客戶端會忽略它。
must-revalidate 一旦資源過期(比如超過max-age),在成功向原始服務器驗證之前,緩存不能用該資源響應后續請求。
no-transform 不得對資源進行轉換或轉變。
only-if-cached 表明客戶端只接受已緩存的響應,并且不要向原始服務器檢查是否有更新的拷貝。
十一、HTTP1.1的缺點
1.無狀態
其實這也不能說是缺點,這算是它的特點之一,至于是缺點還是優點,要分場景來看的。那么什么是無狀態呢?就是指通信過程的上下文信息,每次請求都是獨立、互相無關的,且默認狀態不需要保留狀態信息的。但是在一些場景下,比如前一次請求需要與后一次請求有一定關聯,這個時候無狀態
處理起來就比較麻煩了。
2.臃腫的消息首部
HTTP/1.1 的首部無法壓縮,再加上 cookie 的存在,經常會出現首部大小比請求數據大小還大的情況。
3.明文傳輸
也就是協議里的報文,即傳輸頭信息,不使用二進制,而是使用文本的形式傳輸。這就給中間攔截者造成可乘之機,攔截傳輸內容,獲取敏感信息。
4.隊頭阻塞
http
傳輸是基于請求-應答
的模式進行的,報文必須是一發一收,所有任務被放到一個任務隊列中串行執行。當http
開啟長連接的時候,當前域名下會共用一個TCP
連接,一旦隊首因某些原因卡住,后續只能處于等待狀態,這就是著名的隊頭阻塞
問題。
那么如何解決隊頭阻塞問題?在不升級到HTTP2.0
的前提下,有兩種解決方案:
并發連接。對一個域名分配多個長連接,增加多個任務隊列。就像食堂打飯后排隊付錢,一個隊伍排到門口,現在從之前的一個窗口增加到多個窗口,同一時間做付款操作的同學多了,速度自然也就快起來了。
域名分片。上面講到了對一個域名分配多個長連接,那么也可以分配多個域名。例如分配
static1.baidu.com
、static2.baidu.com
等多個域名加載網站資源,每個域名再分配多個長鏈接,就可以相對解決隊頭阻塞
問題。
注意:域名也不是越多越好,因為每多一個域名,都要涉及到DNS查找
、TCP三次握手
、SSL/TLS
握手,且TCP
有一個慢啟動特點,就是剛開始傳輸慢,慢慢的才會達到一個較快的穩定速度,如果啟用了一個單獨域名,而這個域名只傳輸了一個2KB
的js文件,實際文件傳輸時間遠遠小于握手
時間,就得不償失了。具體哪個地方耗時可以在Chrome
開發面板下Network
中查看具體文件,其中有一個Waterfall
內容,截圖示例如下:
名詞解釋
Queued at: ?從頁面加載到開始請求當前文件的等待時間。
Started at: ?從第幾秒開始請求當前文件。
Queueing: ?在請求隊列中的時間。
Stalled: ?從TCP 連接建立完成,到真正可以傳輸數據之間的時間差,此時間包括代理協商時間。
DNS Lookup: ?當前域名執行DNS查找所花費的時間。
Initial Connection: 建立連接所花費的時間,包括TCP握手/重試和協商SSL。
SSL: ?完成SSL握手所花費的時間(如果是TLS協議,此處顯示的就是TLS)。
Request sent: ?發出網絡請求所花費的時間,通常為一毫秒的時間。
Waiting(TFFB): ?TFFB 是發出頁面請求到接收到應答數據第一個字節的時間。
Content Download: 接收響應數據所花費的時間。
十二、HTTP2.0的優勢
1.頭部壓縮
HTTP1.1
時代,默認情況下前后兩次HTTP
請求沒有關聯,這被稱為無狀態
,請求以及響應頭信息里有很多字段(本文之前已介紹過),不論是否需要,都會以key:value
的形式在網絡中傳輸,尤其對于GET
請求,請求報文幾乎全是請求頭,這個時候就存在非常大的優化空間。HTTP2.0
就針對這個問題采用了HPACK
壓縮算法對頭部內容進行壓縮,大大減少了網絡傳輸。HPACK
壓縮算法的特點是啥?在服務端與客戶端建立一個哈希表,以索引的形式代替頭信息,雙方傳輸就以索引為準,拿到索引值后到哈希表中尋找對應頭內容,以此減少網絡傳輸。
2.多路復用
上面講到了HTTP1.1
隊頭阻塞的問題,雖然采用了長連接以及多域名分片方法在一定程度上規避里隊頭阻塞
,但并沒有從根本上解決問題。比如在有限的帶寬情況下,如何完成優先級較高的請求,而不是一定要按照排隊
的順序。HTTP2.0
是以二進制分幀
的方式來解決所謂的隊頭阻塞
問題。將原來的Headers
、Body
的報文解析成二進制的幀數據,傳輸過程中看到的是10101
的格式。這些二進制幀不存在先后關系,因此也就不會排隊等待,也就沒有了 HTTP 的隊頭阻塞問題。
注意:所謂的亂序,指的是不同ID
的Stream
是亂序的,但同一個Stream ID
的幀一定是按順序傳輸的。二進制幀到達后對方會將Stream ID
相同的二進制幀組裝成完整的請求報文和響應報文。
3.服務器推送
我們知道在目前的HTTP1.1
時代,服務器是被動的
,只有客戶端主動發起請求,服務端才會響應對應內容,是一問一答的模式。并不會主動推送內容給客戶端,除非采用websocket
。而HTTP2.0
就增加了服務器推送
特性,可以對客戶端的一個請求發送多個響應。比如客戶端請求html
頁面的時候,服務器可以將當前頁面用到的js
以及css
等資源一并返回給客戶端,減少后續交互。
當然,客戶端也可以拒絕服務器的推送。
4.解析速度快
服務器解析 HTTP1.1 的請求時,必須不斷地讀入字節,直到遇到分隔符 CRLF 為止。而解析 HTTP2 的請求就不用這么麻煩,因為 HTTP2.0
是基于幀的協議,每個幀都有表示幀長度的字段。
5.優先級
HTTP2.0
可以對比較緊急的請求設置一個較高的優先級,服務器在收到這樣的請求后,可以優先處理。
十三、HTTPS知識點
HTTPS
是超文本傳輸安全協議,加強版的HTTP
,在HTTP
的基礎上對headers
、body
進行加密后再傳輸,大大增加了安全性。簡單的講,HTTPS = HTTP + SSL/TLS
。
至于為何安全,簡要的說就是在之前HTTP
明文傳輸的基礎上增加了對稱加密
、不對稱加密
算法。至于加密的原理及過程,需要額外一篇文章來詳細講解,感興趣的同學可查閱相關資料,這里不再贅述。
與前端相關的另外一個HTTPS
知識點就是:HTTPS
在HTTP
握手的基礎上又增加了一層SSL/TLS
握手。所以安全是要有一定代價的,代價就是在真正連接前又多了個握手的過程。握手的過程這里不再贅述,感興趣的同學可查閱相關資料。主要分以下三類:
RSA 握手
TLS1.2 握手
TLS1.3 握手
十四、HTTP和HTTPS的區別
HTTP
是明文傳輸,不安全的,HTTPS
是加密傳輸,安全的多。HTTP
標準端口是80
,HTTPS
標準端口是443。HTTP
不用認證證書免費,HTTPS
需要認證證書要錢。連接方式不同,
HTTP
三次握手,HTTPS
中TLS1.2
版本7次,TLS1.3
版本6次。HTTP
在OSI
網絡模型中是在應用層,而HTTPS
的TLS
是在傳輸層。HTTP
是無狀態的,HTTPS
是有狀態的。
十五、HTTP代理
目前通常意義上的代理,一般認為是CDN
節點,就是架設在客戶端與原服務器之間的服務器,對客戶端來說它就是服務器,對服務器來說它就是客戶端。主要起到負載均衡
的作用,減少原服務器的壓力,分擔原服務器帶寬,提高用戶訪問資源速度,提高用戶體驗。
什么是CDN
默認情況下,所有資源都會向原服務器請求。這不僅會給原服務器造成較大壓力,還會因距離問題讓客戶端等待較長時間,例如服務器在美國,中國用戶首次請求要跨越大半個地球,顯然比從上海服務器請求更慢。這個時候對于原服務器來說,就需要個代理
,這個代理服務器就被稱為CDN
節點,節點
按照一定規則定期向原服務器更新文件即可,附近的用戶就近訪問當前節點即可,既減輕了原服務器壓力,也減少了請求時間,提高用戶體驗。
代理常見頭部字段
Via
是一個能用首部,由代理服務器添加,適用于正向和反向代理,在請求和響應首部均可出現,這個消息首部可以用來追蹤消息轉發情況,防止循環請求,還可以識別在請求或響應傳遞鏈中消息發送者對于協議的支持能力。
Via:?1.1?vegur
Via:?HTTP/1.1?GWA
Via:?1.0?fred,?1.1?p.yourAddress.net
X-Forwarded-For
是一種獲取用戶真實IP
的字段,不管中間經過多少代理,這個字段始終記錄最初的客戶端的IP
。
相應的,還有X-Forwarded-Host
和X-Forwarded-Proto
,分別記錄客戶端(注意:不包括代理)的域名和協議名。
X-Real-IP
一般記錄真實發出請求的客戶端的IP
,還有X-Forwarded-Host
和X-Forwarded-Proto
分別記錄真實發出請求的客戶端的域名和協議名。
十六、http性能優化相關
其實能看到這里,相信你的心里已經對網絡性能優化有一定的想法了,這里也就做一些簡單的知識點羅列。
DNS預解析
合理控制域名數量
使用HTTP2.0
采用服務端渲染+客戶端渲染的方式
公共類庫存放到CDN上
http返回值
Cache-Control
的max-age
設置較大值,例如6個月,盡可能保持一直緩存,文件更改的時候還一個hash
文件名即可。將CSS放在文件頭部,JavaScript文件放在底部
使用字體圖標iconfont代替圖片圖標
小圖片采用base64壓縮,減少網絡請求
js、css文件壓縮,服務端采用gzip、br等壓縮算法
圖片懶加載。這對于首屏優化非常有用,非首屏需要的圖片在網絡空閑的時候異步加載即可
關于圖片,也可以適當降低圖片質量,或者先加載一個質量較低的圖片顯示給用戶看,之后再加載清晰的圖片展示給用戶。
使用css3代理部分圖標
webpack配置按需加載
減少重繪重排
使用requestAnimationFrame來實現視覺變化
使用Web Workers
降低CSS選擇器的復雜性
使用flexbox布局
使用transform和opacity屬性更改來實現動畫
最后一條建議:避免過度優化
最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。
推薦閱讀
整整4個月了,盡全力組織了源碼共讀活動~
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀
老姚淺談:怎么學JavaScript?
我在阿里招前端,該怎么幫你(可進面試群)
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》10余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助1000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。分享、收藏、點贊、在看我的文章就是對我最大的支持~