一慨亲、HTTP
HTTP(HyperText Transfer Protocol:超文本傳輸協(xié)議)是一種用于分布式、協(xié)作式和超媒體信息系統(tǒng)的應(yīng)用層協(xié)議赊舶。 簡單來說就是一種發(fā)布和接收 HTML 頁面的方法疚沐,被用于在 Web 瀏覽器和網(wǎng)站服務(wù)器之間傳遞信息。
HTTP 默認工作在 TCP 協(xié)議 80 端口秸侣,另外還有 8000 和 8080 也很常用。用戶訪問網(wǎng)站 http:// 打頭的都是標準 HTTP 服務(wù)宠互。
HTTP 協(xié)議以明文方式發(fā)送內(nèi)容味榛,不提供任何方式的數(shù)據(jù)加密,如果攻擊者截取了Web瀏覽器和網(wǎng)站服務(wù)器之間的傳輸報文予跌,就可以直接讀懂其中的信息搏色,因此,HTTP協(xié)議不適合傳輸一些敏感信息券册,比如:信用卡號频轿、密碼等支付信息。
HTTP會話分為三個階段:
- 客戶端建立一條 TCP 連接(如果傳輸層不是 TCP烁焙,也可以是其他適合的連接)航邢。
- 客戶端發(fā)送請求并等待應(yīng)答。
- 服務(wù)器處理請求并送回應(yīng)答骄蝇,回應(yīng)包括一個狀態(tài)碼和對應(yīng)的數(shù)據(jù)膳殷。
從 HTTP/1.1 開始,連接在完成第三階段后不再關(guān)閉九火,客戶端可以再次發(fā)起新的請求赚窃。這意味著第二步和第三步可以連續(xù)進行數(shù)次。
一個HTTP請求一般由四個部分組成:
1).HTTP請求的方法或動作吃既,比如是GET請求還是POST請求。
2).正在請求的URL跨细,就是請求的地址(我們輸入的一般是網(wǎng)址)鹦倚。
3).請求頭,包含一些客戶端環(huán)境信息冀惭,身份驗證信息等震叙。
4).請求體,也就是請求正文散休,請求正文中可以包含客戶提交的查詢字符信息媒楼,表單信息等等。
HTTP請求的兩種方式:
- GET請求:一般用于信息獲取戚丸,使用URL傳遞參數(shù)划址,對所發(fā)送信息的數(shù)量也有限制扔嵌,一般在2000個字符,GET請求一般用于獲取信息夺颤,換句話說痢缎,就是查詢,查詢不會影響數(shù)據(jù)本身世澜。但是GET請求發(fā)送的信息對任何人都是可見的独旷,這樣對數(shù)據(jù)的保密性就比較低了。
- POST請求:一般用于修改服務(wù)器上的資源寥裂。對所發(fā)送信息的數(shù)量無限制嵌洼。通過POST方法一般用來從表單發(fā)送數(shù)據(jù),這些對數(shù)據(jù)對其他人是不可見的封恰,所以相對于GET請求來說保密性就高得多麻养。
一個HTTP響應(yīng)一般由三部分組成:
1)一個數(shù)字和文字組成的狀態(tài)碼,用來顯示請求是成功還是失敗俭驮。
2)響應(yīng)頭回溺,響應(yīng)頭也和請求頭一樣包含許多有用的信息,例如服務(wù)器類型混萝,日期時間遗遵,內(nèi)容類型和長度等等。
3)相應(yīng)體逸嘀,也就是響應(yīng)正文车要。
HTTP狀態(tài)碼由3位數(shù)字構(gòu)成:
首位數(shù)字定義了狀態(tài)碼的類型
1XX:信息類,表示收到Web瀏覽器請求崭倘,正在進一步的處理中翼岁。
2XX:成功,表示用戶請求被正確接收司光,理解和處理琅坡。例如:200 OK。
3XX:重定向残家,表示請求沒有成功榆俺,客戶必須采取進一步的動作。
4XX:客戶端錯誤坞淮,表示客戶端提交的請求有錯誤茴晋。例如:404NOT Found,意味著請求中所引用的文檔不存在回窘。
5XX:服務(wù)器錯誤诺擅,表示服務(wù)器不能完成對請求的處理。
常見狀態(tài)碼:
301:被請求的資源已永久移動到新位置
400: 1啡直、語義有誤烁涌,當前請求無法被服務(wù)器理解苍碟。2、請求參數(shù)有誤烹玉。
403:服務(wù)器已經(jīng)理解請求驰怎,但是拒絕執(zhí)行它。
404:請求失敗二打,請求所希望得到的資源未被在服務(wù)器上發(fā)現(xiàn)县忌。
408: 請求超時。
500: 服務(wù)器遇到了不知道如何處理的情況继效。
501: 此請求方法不被服務(wù)器支持且無法被處理症杏。
503:服務(wù)器沒有準備好處理請求。 常見原因是服務(wù)器因維護或重載而停機瑞信。
504:當服務(wù)器作為網(wǎng)關(guān)厉颤,不能及時得到響應(yīng)時返回此錯誤代碼。
505:服務(wù)器不支持請求中所使用的HTTP協(xié)議版本凡简。
了解了上面的內(nèi)容之后逼友,那么問題來了,當我們在web瀏覽器的地址欄中輸入: www.baidu.com秤涩,然后回車帜乞,到底發(fā)生了什么?
1.對www.baidu.com這個網(wǎng)址進行DNS域名解析筐眷,得到對應(yīng)的IP地址
2.根據(jù)這個IP黎烈,找到對應(yīng)的服務(wù)器,發(fā)起TCP的三次握手
3.建立TCP連接后發(fā)起HTTP請求
4.服務(wù)器響應(yīng)HTTP請求匀谣,瀏覽器得到html文件
5.瀏覽器解析html代碼照棋,并請求html代碼中的資源(如js、css圖片等)(先得到html代碼武翎,才能去找這些資源)
6.瀏覽器對頁面進行渲染呈現(xiàn)給用戶
注:
DNS域名解析采用的是遞歸查詢的方式烈炭,過程是,先去找DNS緩存->緩存找不到就去找根域名服務(wù)器->根域名又會去找下一級宝恶,這樣遞歸查找之后符隙,找到了,給我們的web瀏覽器
為什么HTTP協(xié)議要基于TCP來實現(xiàn)卑惜? TCP是一個端到端的可靠的面相連接的協(xié)議膏执,HTTP基于傳輸層TCP協(xié)議不用擔心數(shù)據(jù)傳輸?shù)母鞣N問題(當發(fā)生錯誤時驻售,會重傳)
最后一步瀏覽器是如何對頁面進行渲染的露久?
a)解析html文件構(gòu)成 DOM樹,
b)解析CSS文件構(gòu)成渲染樹欺栗,
c)邊解析毫痕,邊渲染 征峦,
d)JS 單線程運行,JS有可能修改DOM結(jié)構(gòu)消请,意味著JS執(zhí)行完成前栏笆,后續(xù)所有資源的下載是沒有必要的,所以JS是單線程臊泰,會阻塞后續(xù)資源下載
下面我們來詳細看看這幾個過程的具體細節(jié):
1.域名解析
a)首先會搜索瀏覽器自身的DNS緩存(緩存時間比較短蛉加,大概只有1分鐘,且只能容納1000條緩存)
b)如果瀏覽器自身的緩存里面沒有找到缸逃,那么瀏覽器會搜索系統(tǒng)自身的DNS緩存
c)如果還沒有找到针饥,那么嘗試從 hosts文件里面去找
d)在前面三個過程都沒獲取到的情況下,就遞歸地去域名服務(wù)器去查找需频,具體過程如下
DNS優(yōu)化:兩個方面:DNS緩存丁眼、DNS負載均衡
2.TCP連接(三次握手)
拿到域名對應(yīng)的IP地址之后,User-Agent(一般指瀏覽器)會以一個隨機端口(1024<端口<65535)向服務(wù)器的WEB程序(常用的有httpd昭殉,nginx)等的80端口苞七。這個連接請求(原始的http請求經(jīng)過TCP/IP4層模型的層層封包)到達服務(wù)器端后(這中間有各種路由設(shè)備,局域網(wǎng)內(nèi)除外)挪丢,進入到網(wǎng)卡蹂风,然后是進入到內(nèi)核的TCP/IP協(xié)議棧(用于識別連接請求,解封包吃靠,一層一層的剝開)硫眨,還有可能要經(jīng)過Netfilter防火墻(屬于內(nèi)核的模塊)的過濾,最終達到WEB程序巢块,最終建立了TCP/IP的連接
TCP(Transmission Control Protocol 傳輸控制協(xié)議)是一種面向連接的礁阁、可靠的、基于字節(jié)流的傳輸層通信協(xié)議族奢。
在運用此協(xié)議進行數(shù)據(jù)傳輸前都會進行連接的建立工作(三次握手)
當數(shù)據(jù)傳輸完畢姥闭,連接的雙方都會通知對方要釋放此連接(四次揮手)
tcp標志位有6種標志位
1.SYN(synchronous )建立聯(lián)機
2.ACK(acknowledgement)確認
3.PSH(push)傳送
4.FIN(finsh)結(jié)束
5.RST(reset)重置
6.URG(urgent)緊急
圖解TCP與UDP的三次握手與四次揮手過程
三次握手過程:
第一次握手:Client將標志位SYN置為1,ACK=0越走,隨機產(chǎn)生一個值seq=J棚品,并將該數(shù)據(jù)包發(fā)送給Server。
第二次握手:Server收到數(shù)據(jù)包后由標志位SYN=1知道Client請求建立連接廊敌,Server將標志位SYN和ACK都置為1铜跑,確認號ack =J+1,隨機產(chǎn)生序列號seq=K骡澈,并將該數(shù)據(jù)包發(fā)送給Client以確認連接請求锅纺。
第三次握手:Client收到確認后,檢查ack是否為J+1肋殴,ACK是否為1囤锉,如果正確則將標志位ACK置為1坦弟,ack=K+1,并將該數(shù)據(jù)包發(fā)送給Server官地,Server檢查ack是否為K+1酿傍,ACK是否為1,如果正確則連接建立成功驱入,可以開始傳輸數(shù)據(jù)了赤炒。
四次揮手過程:
第一次揮手:當傳輸?shù)臄?shù)據(jù)到達尾部時,Client向Server發(fā)送FIN = 1標志位亏较,seq = x,用來關(guān)閉Client到Server的數(shù)據(jù)傳送可霎。(Client進入FIN_WAIT_1狀態(tài))
第二次揮手:Server收到FIN后,發(fā)送ACK = 1宴杀,確認序號ack = x+1癣朗,seq=y給Client,Server進入CLOSE_WAIT狀態(tài)旺罢。
第三次揮手:數(shù)據(jù)傳輸完成后旷余,Server發(fā)送FIN = 1,ACK=1,ack=x+1,seq=z用來關(guān)閉Server到Client的數(shù)據(jù)傳送扁达,Server進入LAST_ACK狀態(tài)正卧。
第四次揮手:Client收到FIN后,Client進入TIME_WAIT狀態(tài)跪解,接著發(fā)送ACK=1,ack=z+1,seq=x+1給Server炉旷,Server進入CLOSED狀態(tài),完成四次揮手叉讥。
為什么建立連接是三次握手窘行,而關(guān)閉連接卻是四次揮手呢?
因為當Server端收到Client端的SYN連接請求報文后图仓,可以把ACK和SYN放在一個報文里發(fā)送給客戶端罐盔。(其中ACK報文是用來應(yīng)答的,SYN報文是用來同步的救崔。)但是關(guān)閉連接時惶看,當Server端收到FIN報文時,僅僅表示Client不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)六孵,Server也未必全部數(shù)據(jù)都發(fā)送給對方了纬黎,很可能并不會立即關(guān)閉SOCKET,所以ACK和FIN一般都會分開發(fā)送劫窒。會先回復(fù)一個ACK報文本今,告訴Client端,"你發(fā)的FIN報文我收到了"。只有等到我Server端所有的報文都發(fā)送完了诈泼,我才能發(fā)送FIN報文。
3.建立TCP連接之后煤禽,發(fā)起HTTP請求
HTTP請求報文由三部分組成:請求行铐达,請求頭和請求正文
請求行:用于描述客戶端的請求方式,請求的資源名稱以及使用的HTTP協(xié)議的版本號(例:GET/books/java.html HTTP/1.1)
請求頭:用于描述客戶端請求哪臺主機檬果,以及客戶端的一些環(huán)境信息等
注:這里提一個請求頭 Connection瓮孙,Connection設(shè)置為 keep-alive用于說明 客戶端這邊設(shè)置的是,本次HTTP請求之后并不需要關(guān)閉TCP連接选脊,這樣可以使下次HTTP請求使用相同的TCP通道杭抠,節(jié)省TCP建立連接的時間
請求正文:當使用POST, PUT等方法時,通常需要客戶端向服務(wù)器傳遞數(shù)據(jù)恳啥。這些數(shù)據(jù)就儲存在請求正文中(GET方式是保存在url地址后面偏灿,不會放到這里)
4.服務(wù)器端響應(yīng)http請求,瀏覽器得到html代碼
HTTP響應(yīng)也由三部分組成:狀態(tài)碼钝的,響應(yīng)頭和實體內(nèi)容
狀態(tài)碼:狀態(tài)碼用于表示服務(wù)器對請求的處理結(jié)果
列舉幾種常見的:200(沒有問題) 302(要你去找別人) 304(要你去拿緩存) 307(要你去拿緩存) 403(有這個資源翁垂,但是沒有訪問權(quán)限) 404(服務(wù)器沒有這個資源) 500(服務(wù)器這邊有問題)
若干響應(yīng)頭:響應(yīng)頭用于描述服務(wù)器的基本信息,以及客戶端如何處理數(shù)據(jù)
實體內(nèi)容:服務(wù)器返回給客戶端的數(shù)據(jù)
注:html資源文件應(yīng)該不是通過 HTTP響應(yīng)直接返回去的硝桩,應(yīng)該是通過nginx通過io操作去拿到的吧
5.瀏覽器解析html代碼沿猜,并請求html代碼中的資源
瀏覽器拿到html文件后,就開始解析其中的html代碼碗脊,遇到j(luò)s/css/image等靜態(tài)資源時啼肩,就向服務(wù)器端去請求下載(會使用多線程下載,每個瀏覽器的線程數(shù)不一樣)衙伶,這是時候就用上 keep-alive特性了祈坠,建立一次HTTP連接,可以請求多個資源矢劲,下載資源的順序就是按照代碼里面的順序颁虐,但是由于每個資源大小不一樣,而瀏覽器又是多線程請求請求資源卧须,所以這里顯示的順序并不一定是代碼里面的順序另绩。
6.瀏覽器對頁面進行渲染呈現(xiàn)給用戶
最后,瀏覽器利用自己內(nèi)部的工作機制花嘶,把請求的靜態(tài)資源和html代碼進行渲染笋籽,渲染之后呈現(xiàn)給用戶
瀏覽器是一個邊解析邊渲染的過程。首先瀏覽器解析HTML文件構(gòu)建DOM樹椭员,然后解析CSS文件構(gòu)建渲染樹车海,等到渲染樹構(gòu)建完成后,瀏覽器開始布局渲染樹并將其繪制到屏幕上。這個過程比較復(fù)雜侍芝,涉及到兩個概念: reflow(回流)和repain(重繪)研铆。DOM節(jié)點中的各個元素都是以盒模型的形式存在,這些都需要瀏覽器去計算其位置和大小等州叠,這個過程稱為relow;當盒模型的位置,大小以及其他屬性棵红,如顏色,字體,等確定下來之后,瀏覽器便開始繪制內(nèi)容咧栗,這個過程稱為repain逆甜。頁面在首次加載時必然會經(jīng)歷reflow和repain吁脱。reflow和repain過程是非常消耗性能的群扶,尤其是在移動設(shè)備上昭躺,它會破壞用戶體驗屠缭,有時會造成頁面卡頓禁谦。所以我們應(yīng)該盡可能少的減少reflow和repain溉潭。
JS的解析是由瀏覽器中的JS解析引擎完成的悄窃。JS是單線程運行梧兼,JS有可能修改DOM結(jié)構(gòu)萝挤,意味著JS執(zhí)行完成前稚茅,后續(xù)所有資源的下載是沒有必要的,所以JS是單線程平斩,會阻塞后續(xù)資源下載
總結(jié)一次完整的HTTP請求過程:
域名解析 --> 發(fā)起TCP的3次握手 --> 建立TCP連接后發(fā)起http請求 --> 服務(wù)器響應(yīng)http請求亚享,瀏覽器得到html代碼 --> 瀏覽器解析html代碼,并請求html代碼中的資源(如js绘面、css欺税、圖片等) --> 瀏覽器對頁面進行渲染呈現(xiàn)給用戶
二、HTTPS
HTTPS(Hypertext Transfer Protocol Secure:超文本傳輸安全協(xié)議)是一種透過計算機網(wǎng)絡(luò)進行安全通信的傳輸協(xié)議揭璃。HTTPS 經(jīng)由 HTTP 進行通信晚凿,但利用 SSL/TLS 來加密數(shù)據(jù)包。HTTPS 開發(fā)的主要目的瘦馍,是提供對網(wǎng)站服務(wù)器的身份認證歼秽,保護交換數(shù)據(jù)的隱私與完整性。
HTTPS 默認工作在 TCP 協(xié)議443端口情组,它的工作流程一般如以下方式:
- TCP 三次同步握手
- 客戶端驗證服務(wù)器數(shù)字證書
- DH 算法協(xié)商對稱加密算法的密鑰燥筷、hash 算法的密鑰
- SSL 安全加密隧道協(xié)商完成
- 網(wǎng)頁以加密的方式傳輸,用協(xié)商的對稱加密算法和密鑰加密院崇,保證數(shù)據(jù)機密性肆氓;用協(xié)商的hash算法進行數(shù)據(jù)完整性保護,保證數(shù)據(jù)不被篡改底瓣。
HTTPS 的工作原理
我們都知道 HTTPS 能夠加密信息谢揪,以免敏感信息被第三方獲取,所以很多銀行網(wǎng)站或電子郵箱等等安全級別較高的服務(wù)都會采用 HTTPS 協(xié)議。
客戶端發(fā)起 HTTPS 請求
用戶在瀏覽器里輸入一個 https 網(wǎng)址拨扶,然后連接到 server 的 443 端口凳鬓。服務(wù)端的配置
采用 HTTPS 協(xié)議的服務(wù)器必須要有一套數(shù)字證書,可以自己制作患民,也可以向組織申請缩举,區(qū)別就是自己頒發(fā)的證書需要客戶端驗證通過,才可以繼續(xù)訪問酒奶,而使用受信任的公司申請的證書則不會彈出提示頁面(startssl 就是個不錯的選擇,有 1 年的免費服務(wù))奶赔。
這套證書其實就是一對公鑰和私鑰惋嚎,如果對公鑰和私鑰不太理解,可以想象成一把鑰匙和一個鎖頭站刑,只是全世界只有你一個人有這把鑰匙另伍,你可以把鎖頭給別人,別人可以用這個鎖把重要的東西鎖起來绞旅,然后發(fā)給你摆尝,因為只有你一個人有這把鑰匙,所以只有你才能看到被這把鎖鎖起來的東西因悲。傳送證書
這個證書其實就是公鑰堕汞,只是包含了很多信息,如證書的頒發(fā)機構(gòu)晃琳,過期時間等等讯检。客戶端解析證書
這部分工作是有客戶端的TLS來完成的,首先會驗證公鑰是否有效卫旱,比如頒發(fā)機構(gòu)人灼,過期時間等等,如果發(fā)現(xiàn)異常顾翼,則會彈出一個警告框投放,提示證書存在問題。
如果證書沒有問題适贸,那么就生成一個隨機值灸芳,然后用證書對該隨機值進行加密,就好像上面說的拜姿,把隨機值用鎖頭鎖起來耗绿,這樣除非有鑰匙,不然看不到被鎖住的內(nèi)容砾隅。傳送加密信息
這部分傳送的是用證書加密后的隨機值误阻,目的就是讓服務(wù)端得到這個隨機值,以后客戶端和服務(wù)端的通信就可以通過這個隨機值來進行加密解密了。服務(wù)端解密信息
服務(wù)端用私鑰解密后究反,得到了客戶端傳過來的隨機值(私鑰)寻定,然后把內(nèi)容通過該值進行對稱加密,所謂對稱加密就是精耐,將信息和私鑰通過某種算法混合在一起狼速,這樣除非知道私鑰,不然無法獲取內(nèi)容卦停,而正好客戶端和服務(wù)端都知道這個私鑰向胡,所以只要加密算法夠彪悍,私鑰夠復(fù)雜惊完,數(shù)據(jù)就夠安全僵芹。傳輸加密后的信息
這部分信息是服務(wù)段用私鑰加密后的信息,可以在客戶端被還原小槐。客戶端解密信息
客戶端用之前生成的私鑰解密服務(wù)段傳過來的信息拇派,于是獲取了解密后的內(nèi)容,整個過程第三方即使監(jiān)聽到了數(shù)據(jù)凿跳,也束手無策件豌。
三、HTTP 與 HTTPS 區(qū)別
- HTTP 明文傳輸控嗜,數(shù)據(jù)都是未加密的茧彤,安全性較差,HTTPS(SSL+HTTP) 數(shù)據(jù)傳輸過程是加密的疆栏,安全性較好棘街。
- 使用 HTTPS 協(xié)議需要到 CA(Certificate Authority,數(shù)字證書認證機構(gòu)) 申請證書承边,一般免費證書較少遭殉,因而需要一定費用。證書頒發(fā)機構(gòu)如:Symantec博助、Comodo险污、GoDaddy 和 GlobalSign 等。
- HTTP 頁面響應(yīng)速度比 HTTPS 快富岳,主要是因為 HTTP 使用 TCP 三次握手建立連接蛔糯,客戶端和服務(wù)器需要交換 3 個包,而 HTTPS除了 TCP 的三個包窖式,還要加上 ssl 握手需要的 9 個包蚁飒,所以一共是 12 個包。
- http 和 https 使用的是完全不同的連接方式萝喘,用的端口也不一樣淮逻,前者是 80琼懊,后者是 443。
- HTTPS 其實就是建構(gòu)在 SSL/TLS 之上的 HTTP 協(xié)議爬早,所以哼丈,要比較 HTTPS 比 HTTP 要更耗費服務(wù)器資源。