走在前端的大道上css
本篇將本身讀過的相關 http/https 方法 文章中,對本身有啓發的章節片斷總結在這(會對原文進行刪改),會不斷豐富提煉總結更新。html
URI 包含 URL 和 URN,目前 WEB 只有 URL 比較流行,因此見到的基本都是 URL。前端
超文本傳輸協議(HTTP)是用於傳輸諸如HTML的超媒體文檔的應用層協議。它被設計用於Web瀏覽器和Web服務器之間的通訊,但它也能夠用於其餘目的。 HTTP遵循經典的客戶端-服務端模型,客戶端打開一個鏈接以發出請求,而後等待它收到服務器端響應。 HTTP是無狀態協議,意味着服務器不會在兩個請求之間保留任何數據(狀態)。java
HTTP是明文傳輸的,也就意味着,介於發送端、接收端中間的任意節點均可以知道大家傳輸的內容是什麼。這些節點多是路由器、代理等。python
舉個最多見的例子,用戶登錄。用戶輸入帳號,密碼,採用HTTP的話,只要在代理服務器上作點手腳就能夠拿到你的密碼了。ios
用戶登錄 --> 代理服務器(作手腳)--> 實際受權服務器
在發送端對密碼進行加密?沒用的,雖然別人不知道你原始密碼是多少 ,但可以拿到加密後的帳號密碼,照樣能登錄。git
HTTP是應用層協議,位於HTTP協議之下是傳輸協議TCP。TCP負責傳輸,HTTP則定義了數據如何進行包裝。github
簡單快速、靈活、無鏈接、無狀態web
請求報文 | 響應報文 |
---|---|
請求行 請求頭 空行 請求體 | 狀態行 響應頭 空行 響應體 |
請求報文面試
響應報文
GET ----> 獲取資源
POST ----> 傳輸資源
PUT ----> 更新資源
DELETE ----> 刪除資源
HEAD ----> 獲取報文首部
狀態 | 信息 |
---|---|
1xx | 指示信息 - 表示請求已接受,繼續處理 |
2xx | 成功 - 表示請求已被成功接收 |
3xx | 重定向 - 要完成請求必須進行進一步的操做 |
4xx | 客戶端錯誤 - 請求有語法錯誤或請求沒法實現 |
5xx | 服務器錯誤 - 服務器未能實現合法的請求 |
HTTPS相對於HTTP有哪些不一樣呢?其實就是在HTTP跟TCP中間加多了一層加密層TLS/SSL。
通俗的講,TLS、SSL實際上是相似的東西,SSL是個加密套件,負責對HTTP的數據進行加密。TLS是SSL的升級版。如今提到HTTPS,加密套件基本指的是TLS。
傳輸加密的流程
原先是應用層將數據直接給到TCP進行傳輸,如今改爲應用層將數據給到TLS/SSL,將數據加密後,再給到TCP進行傳輸。
對安全或密碼學基礎有了解的同窗,應該知道常見的加密手段。通常來講,加密分爲對稱加密、非對稱加密(也叫公開密鑰加密)
HTTPS開發的主要目的,是提供對網站服務器的身份認證,保護交換數據的隱私與完整性
谷歌推行一種協議(HTTP 之下SSL之上[TCP]),能夠算是HTTP2的前身,SPDY能夠說是綜合了HTTPS和HTTP二者優勢於一體的傳輸協議,好比
SPDY構成圖:
SPDY位於HTTP之下,TCP和SSL之上,這樣能夠輕鬆兼容老版本的HTTP協議(將HTTP1.x的內容封裝成一種新的frame格式),同時可使用已有的SSL功能。
HTTP2.0能夠說是SPDY的升級版(其實本來也是基於SPDY設計的),可是,HTTP2.0 跟 SPDY 仍有不一樣的地方,主要是如下兩點
http2 新特性
chrome=>Network=>Name欄右鍵=>√Protocol
本節參考文章:簡單比較 http https http2、HTTPS科普掃盲帖
關於跨域,有兩個誤區:
✔ 跨域只存在於瀏覽器端,不存在於安卓/ios/Node.js/python/ java等其它環境
✔ 跨域請求能發出去,服務端能收到請求並正常返回結果,只是結果被瀏覽器攔截了之因此會跨域,是由於受到了同源策略的限制,同源策略要求源相同才能正常進行通訊,即協議、域名、端口號都徹底一致。
可是script標籤可以加載非同源的資源,不受同源策略的影響。
以下圖所示:
只要瀏覽器檢測到響應頭帶上了CORS,而且容許的源包括了本網站,那麼就不會攔截請求響應。
CORS把請求分爲兩種,一種是簡單請求,另外一種是須要觸發預檢請求,這二者是相對的,怎樣纔算「不簡單」?只要屬於下面的其中一種就不是簡單請求:
(1)使用了除GET/POST/HEAD以外的請求方式,如PUT/DELETE
(2)使用了除Accept/Accept-Language/Content-Language/Last-Event-ID/Content-Type:只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
等幾個經常使用的http頭這個時候就認爲須要先發個預檢請求,預檢請求使用OPTIONS方式去檢查當前請求是否安全
代碼裏面只發了一個請求,但在控制檯看到了兩個請求,第一個是OPTIONS,服務端返回:
詳見阮一峯的跨域資源共享CORS詳解
JSONP是利用了script標籤可以跨域,以下代碼所示:
function updateList (data) { console.log(data); } $body.append(‘<script src=「http://otherdomain.com/request?callback=updateList"></script>');
代碼先定義一個全局函數,而後把這個函數名經過callback參數添加到script標籤的src,script的src就是須要跨域的請求,而後這個請求返回可執行的JS文本:// script響應返回的js內容爲
updateList([{ name: 'hello' }]);
因爲它是一個js,而且已經定義了upldateList函數,因此能正常執行,而且跨域的數據經過傳參獲得。這就是JSONP的原理。
跨域分爲兩種,一種是跨域請求,另外一種訪問跨域的頁面,跨域請求能夠經過CORS/JSONP等方法進行訪問,跨域的頁面主要經過postMesssage的方式。因爲跨域請求不但能發出去還能帶上cookie,因此要規避跨站請求僞造攻擊的風險,特別是涉及到錢的那種請求。
本節參考文章:我知道的跨域與安全
主要的過程是:
1.瀏覽器解析 -> 2.查詢緩存 -> 3.dns查詢 -> 4.創建連接 -> 5.服務器處理請求 -> 6.服務器發送響應 -> 7.客戶端收到頁面 -> 8.解析HTML -> 9.構建渲染樹 -> 10.開始顯示內容(白屏時間) -> 11.首屏內容加載完成(首屏時間) -> 12.用戶可交互(DOMContentLoaded) -> 13.加載完成(load)
跳轉-->應用緩存-->dns-->tcp-->request-->response
本節摘要:
當咱們在瀏覽器輸入網址並回車後,一切從這裏開始。
咱們在瀏覽器輸入網址,其實就是要向服務器請求咱們想要的頁面內容,全部瀏覽器首先要確認的是域名所對應的服務器在哪裏。將域名解析成對應的服務器IP地址這項工做,是由DNS服務器來完成的。
客戶端收到你輸入的域名地址後,它首先去找本地的hosts文件,檢查在該文件中是否有相應的域名、IP對應關係,若是有,則向其IP地址發送請求,若是沒有,再去找DNS服務器。通常用戶不多去編輯修改hosts文件。
DNS服務器層次結構
瀏覽器客戶端向本地DNS服務器發送一個含有域名www.cnblogs.com的DNS查詢報文。本地DNS服務器把查詢報文轉發到根DNS服務器,根DNS服務器注意到其com後綴,因而向本地DNS服務器返回comDNS服務器的IP地址。本地DNS服務器再次向comDNS服務器發送查詢請求,comDNS服務器注意到其www.cnblogs.com後綴並用負責該域名的權威DNS服務器的IP地址做爲迴應。最後,本地DNS服務器將含有www.cnblogs.com的IP地址的響應報文發送給客戶端。
從客戶端到本地服務器屬於遞歸查詢,而DNS服務器之間的交互屬於迭代查詢。正常狀況下,本地DNS服務器的緩存中已有comDNS服務器的地址,所以請求根域名服務器這一步不是必需的。
費了一頓周折終於拿到服務器IP了,下一步天然就是連接到該服務器。對於客戶端與服務器的TCP連接,必然要說的就是『三次握手』。
三次握手
客戶端發送一個帶有SYN標誌的數據包給服務端,服務端收到後,回傳一個帶有SYN/ACK標誌的數據包以示傳達確認信息,最後客戶端再回傳一個帶ACK標誌的數據包,表明握手結束,鏈接成功。
上圖也能夠這麼理解:
客戶端:「你好,在家不,有你快遞。」
服務端:「在的,送來就行。」
客戶端:「好嘞。」
TCP三次握手
client----->server:SYN(發起一個TCP鏈接,同步報文)server----->client:SYN+ACK(應答報文,表示已建立鏈接)
client----->server:ACK(應答報文,表示收到已鏈接)
與服務器創建了鏈接後,就能夠向服務器發起請求了。這裏咱們先看下請求報文的結構(以下圖):
請求報文
在瀏覽器中查看報文首部(以google瀏覽器爲例):
請求行包括請求方法、URI、HTTP版本。首部字段傳遞重要信息,包括請求首部字段、通用首部字段和實體首部字段。咱們能夠從報文中看到發出的請求的具體信息。具體每一個首部字段的做用,這裏不作過多闡述。
服務器端收到請求後的由web服務器(準確說應該是http服務器)處理請求,諸如Apache、Ngnix、IIS等。web服務器解析用戶請求,知道了須要調度哪些資源文件,再經過相應的這些資源文件處理用戶請求和參數,並調用數據庫信息,最後將結果經過web服務器返回給瀏覽器客戶端。
服務器處理請求
在HTTP裏,有請求就會有響應,哪怕是錯誤信息。這裏咱們一樣看下響應報文的組成結構:
響應報文
在響應結果中都會有個一個HTTP狀態碼,好比咱們熟知的200、30一、40四、500等。經過這個狀態碼咱們能夠知道服務器端的處理是否正常,並能瞭解具體的錯誤。
狀態碼由3位數字和緣由短語組成。根據首位數字,狀態碼能夠分爲五類:
狀態碼類別
爲了不服務器與客戶端雙方的資源佔用和損耗,當雙方沒有請求或響應傳遞時,任意一方均可以發起關閉請求。與建立TCP鏈接的3次握手相似,關閉TCP鏈接,須要4次握手。
上圖能夠這麼理解:
客戶端:「兄弟,我這邊沒數據要傳了,咱關閉鏈接吧。」
服務端:「收到,我看看我這邊有木有數據了。」
服務端:「兄弟,我這邊也沒數據要傳你了,咱能夠關閉鏈接了。」
客戶端:「好嘞。」
由客戶端發起的關閉鏈接
* client----->server:FIN(請求關閉鏈接) * server----->client:ACK(收到了鏈接,但不會當即關閉,等到報文都發送完再回復一個FIN) * server----->client:FIN * client----->server:ACK(收到關閉)
由服務端發起的關閉鏈接
* 當http設置了keepalive定時關閉,服務端會在結束數據傳送後關閉TCP鏈接
準確地說,瀏覽器須要加載解析的不只僅是HTML,還包括CSS、JS。以及還要加載圖片、視頻等其餘媒體資源。
瀏覽器經過解析HTML,生成DOM樹,解析CSS,生成CSS規則樹,而後經過DOM樹和CSS規則樹生成渲染樹。渲染樹與DOM樹不一樣,渲染樹中並無head、display爲none等沒必要顯示的節點。
要注意的是,瀏覽器的解析過程並不是是串連進行的,好比在解析CSS的同時,能夠繼續加載解析HTML,但在解析執行JS腳本時,會中止解析後續HTML,這就會出現阻塞問題,關於JS阻塞相關問題,這裏不過多闡述,後面會單獨開篇講解。
根據渲染樹佈局,計算CSS樣式,即每一個節點在頁面中的大小和位置等幾何信息。HTML默認是流式佈局的,CSS和js會打破這種佈局,改變DOM的外觀樣式以及大小和位置。這時就要提到兩個重要概念:repaint和reflow。
repaint:屏幕的一部分重畫,不影響總體佈局,好比某個CSS的背景色變了,但元素的幾何尺寸和位置不變。reflow: 意味着元件的幾何尺寸變了,咱們須要從新驗證並計算渲染樹。是渲染樹的一部分或所有發生了變化。這就是Reflow,或是Layout。
因此咱們應該儘可能減小reflow和repaint,我想這也是爲何如今不多有用table佈局的緣由之一。
最後瀏覽器繪製各個節點,將頁面展現給用戶。
拓展閱讀:面試必考之http狀態碼有哪些、CDN與DNS知識彙總、前端工程師系列,TCP複習及濃縮總結(全乾貨,支持面試)
推薦必讀:5分鐘讓你明白HTTP協議、分分鐘讓你理解HTTPS
本節參考文章:」天龍八步「細說瀏覽器輸入URL後發生了什麼
瀏覽器查看緩存,若是請求資源在緩存中而且新鮮,跳轉到轉碼步驟
檢驗新鮮一般有兩個HTTP頭進行控制Expires和Cache-Control:
瀏覽器獲取主機ip地址(DNS解析),過程以下:
打開一個socket與目標IP地址,端口創建TCP連接,三次握手以下:
瀏覽器接收HTTP響應,而後根據狀況選擇關閉TCP鏈接或者保留重用,關閉TCP鏈接的四次握手以下:
構建DOM樹:
構建CSSOM樹:
根據DOM樹和CSSOM樹構建渲染樹:
從DOM樹的根節點遍歷全部可見節點,不可見節點包括:
發佈可視節點的內容和計算樣式
js解析以下:
OSI 七層涵蓋:物理層,數據鏈路層,網絡層,傳輸層,會話層,表示層,應用層;
五層因特網協議棧其實就是:
五層模型就是"會話,表示,應用層"同爲一層;
DNS是應用層協議,事實上他是爲其餘應用層協議工做的,包括不限於HTTP和SMTP以及FTP,用於將用戶提供的主機名解析爲ip地址。
具體過程以下:
(1)瀏覽器緩存: 當用戶經過瀏覽器訪問某域名時,瀏覽器首先會在本身的緩存中查找是否有該域名對應的IP地址(若曾經訪問過該域名且沒有清空緩存便存在);
(2)系統緩存: 當瀏覽器緩存中無域名對應IP則會自動檢查用戶計算機系統Hosts文件DNS緩存是否有該域名對應IP;
(3)路由器緩存: 當瀏覽器及系統緩存中均無域名對應IP則進入路由器緩存中檢查,以上三步均爲客戶端的DNS緩存;
(4)ISP(互聯網服務提供商)DNS緩存: 當在用戶客服端查找不到域名對應IP地址,則將進入ISP DNS緩存中進行查詢。好比你用的是電信的網絡,則會進入電信的DNS緩存服務器中進行查找;(或者向網絡設置中指定的local DNS進行查詢,若是在PC指定了DNS的話,若是沒有設置好比DNS動態獲取,則向ISP DNS發起查詢請求)
(5)根域名服務器: 當以上均未完成,則進入根服務器進行查詢。全球僅有13臺根域名服務器,1個主根域名服務器,其他12爲輔根域名服務器。根域名收到請求後會查看區域文件記錄,若無則將其管轄範圍內頂級域名(如.com)服務器IP告訴本地DNS服務器;
(6)頂級域名服務器: 頂級域名服務器收到請求後查看區域文件記錄,若無則將其管轄範圍內主域名服務器的IP地址告訴本地DNS服務器;
(7)主域名服務器: 主域名服務器接受到請求後查詢本身的緩存,若是沒有則進入下一級域名服務器進行查找,並重復該步驟直至找到正確記錄;
(8)保存結果至緩存: 本地域名服務器把返回的結果保存到緩存,以備下一次使用,同時將該結果反饋給客戶端,客戶端經過這個IP地址與web服務器創建連接。