成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

輸入U(xiǎn)RL到瀏覽器顯示頁(yè)面的過(guò)程,搜集各方面資料總結(jié)一下

adie / 2709人閱讀

摘要:通用頭部這也是開發(fā)人員見(jiàn)過(guò)的最多的信息,包括如下請(qǐng)求的服務(wù)器地址請(qǐng)求方式請(qǐng)求的返回狀態(tài)碼,如代表成功請(qǐng)求的遠(yuǎn)程服務(wù)器地址會(huì)轉(zhuǎn)為譬如,在跨域拒絕時(shí),可能是為,狀態(tài)碼為等當(dāng)然,實(shí)際上可能的組合有很多。

面試中經(jīng)常會(huì)被問(wèn)到這個(gè)問(wèn)題吧,唉,我最開始被問(wèn)到的時(shí)候也就能大概說(shuō)一些流程。被問(wèn)得多了,自己就想去找找這個(gè)問(wèn)題的全面回答,于是乎搜了很多資料和網(wǎng)上的文章,根據(jù)那些文章寫一個(gè)總結(jié)。

寫得不好,或者有意見(jiàn)的直接噴,不用走流程。也歡迎大佬指點(diǎn)

首先這不是小問(wèn)題,能把里面的過(guò)程說(shuō)清楚真的很麻煩,然后下面我把這些知識(shí)點(diǎn),按流程的形式總結(jié)的:

從瀏覽器接收url到開啟網(wǎng)絡(luò)請(qǐng)求線程

開啟網(wǎng)絡(luò)線程到發(fā)出一個(gè)完整的http請(qǐng)求

從服務(wù)器接收到請(qǐng)求到對(duì)應(yīng)后臺(tái)接收到請(qǐng)求

后臺(tái)和前臺(tái)的http交互

http的緩存問(wèn)題

瀏覽器接收到http數(shù)據(jù)包后的解析流程

CSS的可視化格式模型

JS引擎解析過(guò)程

跨域、web安全、hybrid等等

1. 從瀏覽器接收url到開啟網(wǎng)絡(luò)請(qǐng)求線程

多進(jìn)程的瀏覽器

瀏覽器是多進(jìn)程的,有一個(gè)主控進(jìn)程,以及每一個(gè)tab頁(yè)面都會(huì)新開一個(gè)進(jìn)程(某些情況下多個(gè)tab會(huì)合并進(jìn)程)。

進(jìn)程可能包括主控進(jìn)程,插件進(jìn)程,GPU,tab頁(yè)(瀏覽器內(nèi)核)等等。

Browser進(jìn)程:瀏覽器的主進(jìn)程(負(fù)責(zé)協(xié)調(diào)、主控),只有一個(gè)

第三方插件進(jìn)程:每種類型的插件對(duì)應(yīng)一個(gè)進(jìn)程,僅當(dāng)使用該插件時(shí)才創(chuàng)建

GPU進(jìn)程:最多一個(gè),用于3D繪制

瀏覽器渲染進(jìn)程(內(nèi)核):默認(rèn)每個(gè)Tab頁(yè)面一個(gè)進(jìn)程,互不影響,控制頁(yè)面渲染,腳本執(zhí)行,事件處理等(有時(shí)候會(huì)優(yōu)化,如多個(gè)空白tab會(huì)合并成一個(gè)進(jìn)程)

多線程的瀏覽器內(nèi)核

每一個(gè)tab頁(yè)面可以看作是瀏覽器內(nèi)核進(jìn)程,然后這個(gè)進(jìn)程是多線程的,它有幾大類子線程:

GUI渲染線程

JS引擎線程

事件觸發(fā)線程

定時(shí)器觸發(fā)線程

http異步網(wǎng)絡(luò)請(qǐng)求線程

解析URL

輸入U(xiǎn)RL后,會(huì)進(jìn)行解析(URL的本質(zhì)就是統(tǒng)一資源定位符)

URL一般包括幾大部分:

protocol,協(xié)議頭,譬如有http,ftp,https等

host,主機(jī)域名或IP地址

port,端口號(hào)

path,目錄路徑

query,即查詢參數(shù)

fragment,即 #后的hash值,一般用來(lái)定位到某個(gè)位置

網(wǎng)絡(luò)請(qǐng)求都是多帶帶的線程

每次網(wǎng)絡(luò)請(qǐng)求時(shí)都需要開辟多帶帶的線程進(jìn)行,譬如如果URL解析到http協(xié)議,就會(huì)新建一個(gè)網(wǎng)絡(luò)線程去處理資源下載。

因此瀏覽器會(huì)根據(jù)解析出得協(xié)議,開辟一個(gè)網(wǎng)絡(luò)線程,前往請(qǐng)求資源。

2. 開啟網(wǎng)絡(luò)線程到發(fā)出一個(gè)完整的http請(qǐng)求

DNS查詢得到IP

如果輸入的是域名,需要進(jìn)行dns解析成IP,大致流程:

如果瀏覽器有緩存,直接使用瀏覽器緩存,否則使用本機(jī)緩存,再?zèng)]有的話就是用host
如果本地沒(méi)有,就向dns域名服務(wù)器查詢(當(dāng)然,中間可能還會(huì)經(jīng)過(guò)路由,也有緩存等),查詢到對(duì)應(yīng)的IP
注意,域名查詢時(shí)有可能是經(jīng)過(guò)了CDN調(diào)度器的(如果有cdn存儲(chǔ)功能的話)。

而且,需要知道dns解析是很耗時(shí)的,因此如果解析域名過(guò)多,會(huì)讓首屏加載變得過(guò)慢,可以考慮 dns-prefetch優(yōu)化。
這一塊可以深入展開,具體請(qǐng)去網(wǎng)上搜索,這里就不占篇幅了(網(wǎng)上可以看到很詳細(xì)的解答)。

tcp/ip請(qǐng)求

http的本質(zhì)就是 tcp/ip請(qǐng)求。
需要了解三次握手規(guī)則建立連接以及斷開連接時(shí)的四次揮手。
tcp將http長(zhǎng)報(bào)文劃分為短報(bào)文,通過(guò)三次握手與服務(wù)端建立連接,進(jìn)行可靠傳輸。

三次握手:
1.客戶端給服務(wù)器發(fā)確實(shí)是當(dāng)前服務(wù)器
2.服務(wù)器給客戶端回應(yīng),我是你要訪問(wèn)的當(dāng)前服務(wù)器
3.客戶端回應(yīng),我是客戶端

四次揮手:
1.發(fā)起者:關(guān)閉主動(dòng)傳輸信息的通道,只能接收信息
2.接受者:收到通道關(guān)閉的信息
3.接受者:也關(guān)閉主動(dòng)傳輸信息的通道
4.發(fā)起者:接收到數(shù)據(jù),關(guān)閉通道,雙方無(wú)法通信

tcp/ip的并發(fā)限制

瀏覽器對(duì)同一域名下并發(fā)的tcp連接是有限制的(2-10個(gè)不等)。
而且在http1.0中往往一個(gè)資源下載就需要對(duì)應(yīng)一個(gè)tcp/ip請(qǐng)求。
所以針對(duì)這個(gè)瓶頸,又出現(xiàn)了很多的資源優(yōu)化方案。(感興趣的朋友請(qǐng)自行搜索,資料很多)

get和post的區(qū)別

這個(gè)東西網(wǎng)上的資料也很多,這兒就大概描述一下在tcp/ip層面的區(qū)別,在http層面的區(qū)別請(qǐng)讀者自行搜索:
get和post本質(zhì)都是tcp/ip。
get會(huì)產(chǎn)生一個(gè)tcp數(shù)據(jù)包,post兩個(gè)。

具體就是:

get請(qǐng)求時(shí),瀏覽器會(huì)把 headers和 data一起發(fā)送出去,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù)),
post請(qǐng)求時(shí),瀏覽器先發(fā)送 headers,服務(wù)器響應(yīng) 100continue,瀏覽器再發(fā)送 data,服務(wù)器響應(yīng)200(返回?cái)?shù)據(jù))。

然后有讀者可能以前了解過(guò)OSI的七層:物理層、 數(shù)據(jù)鏈路層、 網(wǎng)絡(luò)層、 傳輸層、 會(huì)話層、 表示層、 應(yīng)用層

這兒就不班門弄虎了,列一下內(nèi)容,需要深入理解的讀者請(qǐng)自行搜索,計(jì)算機(jī)網(wǎng)絡(luò)相關(guān)的資料。

1.應(yīng)用層(dns,http) DNS解析成IP并發(fā)送http請(qǐng)求
2.傳輸層(tcp,udp) 建立tcp連接(三次握手)
3.網(wǎng)絡(luò)層(IP,ARP) IP尋址
4.數(shù)據(jù)鏈路層(PPP) 封裝成幀
5.物理層(利用物理介質(zhì)傳輸比特流) 物理傳輸(然后傳輸?shù)臅r(shí)候通過(guò)雙絞線,電磁波等各種介質(zhì))
6.表示層:主要處理兩個(gè)通信系統(tǒng)中交換信息的表示方式,包括數(shù)據(jù)格式交換,數(shù)據(jù)加密與解密,數(shù)據(jù)壓縮與終端類型轉(zhuǎn)換等
7.會(huì)話層:它具體管理不同用戶和進(jìn)程之間的對(duì)話,如控制登陸和注銷過(guò)程

3. 從服務(wù)器接收到請(qǐng)求到對(duì)應(yīng)后臺(tái)接收到請(qǐng)求

后端的操作有點(diǎn)多,我這兒也就不秀自己知識(shí)面低下了,哈哈

負(fù)載均衡

對(duì)于大型的項(xiàng)目,由于并發(fā)訪問(wèn)量很大,所以往往一臺(tái)服務(wù)器是吃不消的,所以一般會(huì)有若干臺(tái)服務(wù)器組成一個(gè)集群,然后配合反向代理實(shí)現(xiàn)負(fù)載均衡。(據(jù)說(shuō)現(xiàn)在node在微服務(wù)的項(xiàng)目方面越來(lái)越猛,大并發(fā)也不在話下,正在研究node,希望后面能寫一個(gè)心得)

簡(jiǎn)單的說(shuō):用戶發(fā)起的請(qǐng)求都指向調(diào)度服務(wù)器(反向代理服務(wù)器,譬如安裝了nginx控制負(fù)載均衡),然后調(diào)度服務(wù)器根據(jù)實(shí)際的調(diào)度算法,分配不同的請(qǐng)求給對(duì)應(yīng)集群中的服務(wù)器執(zhí)行,然后調(diào)度器等待實(shí)際服務(wù)器的HTTP響應(yīng),并將它反饋給用戶。

后臺(tái)的處理

一般后臺(tái)都是部署到容器中的,所以一般為:

1.先是容器接受到請(qǐng)求(如tomcat容器)
2.然后對(duì)應(yīng)容器中的后臺(tái)程序接收到請(qǐng)求(如java程序)
3.然后就是后臺(tái)會(huì)有自己的統(tǒng)一處理,處理完后響應(yīng)響應(yīng)結(jié)果

概括下:
1.一般有的后端是有統(tǒng)一的驗(yàn)證的,如安全攔截,跨域驗(yàn)證
2.如果這一步不符合規(guī)則,就直接返回了相應(yīng)的http報(bào)文(如拒絕請(qǐng)求等)
3.然后當(dāng)驗(yàn)證通過(guò)后,才會(huì)進(jìn)入實(shí)際的后臺(tái)代碼,此時(shí)是程序接收到請(qǐng)求,然后執(zhí)行(譬如查詢數(shù)據(jù)庫(kù),大量計(jì)算等等)
4.等程序執(zhí)行完畢后,就會(huì)返回一個(gè)http響應(yīng)包(一般這一步也會(huì)經(jīng)過(guò)多層封裝)
5.然后就是將這個(gè)包從后端發(fā)送到前端,完成交互

4.后臺(tái)和前臺(tái)的http交互

前后端交互時(shí),http報(bào)文作為信息的載體。

http報(bào)文結(jié)構(gòu)
報(bào)文一般包括了: 通用頭部, 請(qǐng)求/響應(yīng)頭部, 請(qǐng)求/響應(yīng)體。學(xué)過(guò)計(jì)算機(jī)網(wǎng)絡(luò)的讀者應(yīng)超級(jí)熟悉。

通用頭部
這也是開發(fā)人員見(jiàn)過(guò)的最多的信息,包括如下:

Request Url: 請(qǐng)求的web服務(wù)器地址
Request Method: 請(qǐng)求方式(Get、POST、OPTIONS、PUT、HEAD、DELETE、CONNECT、TRACE)
Status Code: 請(qǐng)求的返回狀態(tài)碼,如200代表成功
Remote Address: 請(qǐng)求的遠(yuǎn)程服務(wù)器地址(會(huì)轉(zhuǎn)為IP)
譬如,在跨域拒絕時(shí),可能是method為 options,狀態(tài)碼為 404/405等(當(dāng)然,實(shí)際上可能的組合有很多)。

其中,Method的話一般分為兩批次:

HTTP1.0定義了三種請(qǐng)求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請(qǐng)求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

相信知道RESTFUL的讀者應(yīng)該很熟悉,現(xiàn)在在前端后端開發(fā)使用頻繁的也就是get,post,put,delete,也是我們熟知的四大操作"增刪改查"。

狀態(tài)碼:這是進(jìn)行請(qǐng)求和回應(yīng)的關(guān)鍵信息,官方有最全的狀態(tài)碼信息,這兒就列幾個(gè)常見(jiàn)的:

200——表明該請(qǐng)求被成功地完成,所請(qǐng)求的資源發(fā)送回客戶端
304——自從上次請(qǐng)求后,請(qǐng)求的網(wǎng)頁(yè)未修改過(guò),請(qǐng)客戶端使用本地緩存
400——客戶端請(qǐng)求有錯(cuò)(譬如可以是安全模塊攔截)
401——請(qǐng)求未經(jīng)授權(quán)
403——禁止訪問(wèn)(譬如可以是未登錄時(shí)禁止)
404——資源未找到
500——服務(wù)器內(nèi)部錯(cuò)誤
503——服務(wù)不可用

其他的請(qǐng)讀者自行去搜索官方介紹。

對(duì)于狀態(tài)碼:
數(shù)字1開頭的表示:請(qǐng)求已經(jīng)接收,繼續(xù)處理
數(shù)字2開頭的表示:請(qǐng)求成功,已經(jīng)被服務(wù)器成功處理
數(shù)字3開頭的表示:需要客戶端采取進(jìn)一步的操作才能完成請(qǐng)求
數(shù)字4開頭的表示:客戶端看起來(lái)可能發(fā)生了錯(cuò)誤,妨礙了服務(wù)器的處理
數(shù)字5開頭的:表示服務(wù)器在處理請(qǐng)求的過(guò)程中有錯(cuò)誤或者異常狀態(tài)發(fā)生,也有可能是服務(wù)器意識(shí)到以當(dāng)前的軟硬件資源無(wú)法完成對(duì)請(qǐng)求的處理

請(qǐng)求/響應(yīng)頭部

請(qǐng)求和響應(yīng)頭部也是分析時(shí)常用到的。常用的請(qǐng)求頭部(部分):

Accept: 接收類型,表示瀏覽器支持的MIME類型(對(duì)標(biāo)服務(wù)端返回的Content-Type)
Accept-Encoding:瀏覽器支持的壓縮類型,如gzip等,超出類型不能接收
Content-Type:客戶端發(fā)送出去實(shí)體內(nèi)容的類型
Cache-Control: 指定請(qǐng)求和響應(yīng)遵循的緩存機(jī)制,如no-cache
If-Modified-Since:對(duì)應(yīng)服務(wù)端的Last-Modified,用來(lái)匹配看文件是否變動(dòng),只能精確到1s之內(nèi),http1.0中
Expires:緩存控制,在這個(gè)時(shí)間內(nèi)不會(huì)請(qǐng)求,直接使用緩存,http1.0,而且是服務(wù)端時(shí)間
Max-age:代表資源在本地緩存多少秒,有效時(shí)間內(nèi)不會(huì)請(qǐng)求,而是使用緩存,http1.1中
If-None-Match:對(duì)應(yīng)服務(wù)端的ETag,用來(lái)匹配文件內(nèi)容是否改變(非常精確),http1.1中
Cookie:有cookie并且同域訪問(wèn)時(shí)會(huì)自動(dòng)帶上
Connection:當(dāng)瀏覽器與服務(wù)器通信時(shí)對(duì)于長(zhǎng)連接如何進(jìn)行處理,如keep-alive
Host:請(qǐng)求的服務(wù)器URL
Origin:最初的請(qǐng)求是從哪里發(fā)起的(只會(huì)精確到端口),Origin比Referer更尊重隱私
Referer:該頁(yè)面的來(lái)源URL(適用于所有類型的請(qǐng)求,會(huì)精確到詳細(xì)頁(yè)面地址,csrf攔截常用到這個(gè)字段)
User-Agent:用戶客戶端的一些必要信息,如UA頭部等

常用的響應(yīng)頭部:

Access-Control-Allow-Headers: 服務(wù)器端允許的請(qǐng)求Headers
Access-Control-Allow-Methods: 服務(wù)器端允許的請(qǐng)求方法
Access-Control-Allow-Origin: 服務(wù)器端允許的請(qǐng)求Origin頭部(譬如為*)
Content-Type:服務(wù)端返回的實(shí)體內(nèi)容的類型
Date:數(shù)據(jù)從服務(wù)器發(fā)送的時(shí)間
Cache-Control:告訴瀏覽器或其他客戶,什么環(huán)境可以安全的緩存文檔
Last-Modified:請(qǐng)求資源的最后修改時(shí)間
Expires:應(yīng)該在什么時(shí)候認(rèn)為文檔已經(jīng)過(guò)期,從而不再緩存它
Max-age:客戶端的本地資源應(yīng)該緩存多少秒,開啟了Cache-Control后有效
ETag:請(qǐng)求變量的實(shí)體標(biāo)簽的當(dāng)前值
Set-Cookie:設(shè)置和頁(yè)面關(guān)聯(lián)的cookie,服務(wù)器通過(guò)這個(gè)頭部把cookie傳給客戶端
Keep-Alive:如果客戶端有keep-alive,服務(wù)端也會(huì)有響應(yīng)(如timeout=38)
Server:服務(wù)器的一些相關(guān)信息

請(qǐng)求頭部和響應(yīng)頭部是有對(duì)應(yīng)關(guān)系的:例如
1.請(qǐng)求頭部的 Accept要和響應(yīng)頭部的 Content-Type匹配,否則會(huì)報(bào)錯(cuò)。
2.跨域請(qǐng)求時(shí),請(qǐng)求頭部的 Origin要匹配響應(yīng)頭部的 Access-Control-Allow-Origin,否則會(huì)報(bào)跨域錯(cuò)誤。
3.在使用緩存時(shí),請(qǐng)求頭部的 If-Modified-Since、 If-None-Match分別和響應(yīng)頭部的 Last-Modified、 ETag對(duì)應(yīng)。

更多的對(duì)應(yīng)關(guān)系請(qǐng)讀者自行搜索。

請(qǐng)求/響應(yīng)實(shí)體

做http請(qǐng)求時(shí),除了頭部,還有消息實(shí)體,一般來(lái)說(shuō),請(qǐng)求實(shí)體中會(huì)將一些需要的參數(shù)都放入進(jìn)入(用于post請(qǐng)求)。譬如實(shí)體中可以放參數(shù)的序列化形式( a=1&b=2這種),或者直接放表單對(duì)象( FormData對(duì)象,上傳時(shí)可以?shī)A雜參數(shù)以及文件),等等。

而一般響應(yīng)實(shí)體中,就是放服務(wù)端需要傳給客戶端的內(nèi)容。一般現(xiàn)在的接口請(qǐng)求時(shí),實(shí)體中就是對(duì)于的信息的json格式。

cookie以及優(yōu)化

cookie是瀏覽器的一種本地存儲(chǔ)方式,一般用來(lái)幫助客戶端和服務(wù)端通信的,常用來(lái)進(jìn)行身份校驗(yàn),結(jié)合服務(wù)端的session使用。

常用的場(chǎng)景如下:

用戶登陸后,服務(wù)端會(huì)生成一個(gè)session,session中有對(duì)于用戶的信息(如用戶名、密碼等),然后會(huì)有一個(gè)sessionid(相當(dāng)于是服務(wù)端的這個(gè)session對(duì)應(yīng)的key),然后服務(wù)端在登錄頁(yè)面中寫入cookie,值就是:jsessionid=xxx,然后瀏覽器本地就有這個(gè)cookie了,以后訪問(wèn)同域名下的頁(yè)面時(shí),自動(dòng)帶上cookie,自動(dòng)檢驗(yàn),在有效時(shí)間內(nèi)無(wú)需二次登陸。

一般來(lái)說(shuō),cookie是不允許存放敏感信息的(千萬(wàn)不要明文存儲(chǔ)用戶名、密碼),因?yàn)榉浅2话踩?,如果一定要?qiáng)行存儲(chǔ),首先,一定要在cookie中設(shè)置 httponly(這樣就無(wú)法通過(guò)js操作了)。

另外,由于在同域名的資源請(qǐng)求時(shí),瀏覽器會(huì)默認(rèn)帶上本地的cookie,針對(duì)這種情況,在某些場(chǎng)景下是需要優(yōu)化的。

例如以下場(chǎng)景:

客戶端在域名A下有cookie(這個(gè)可以是登陸時(shí)由服務(wù)端寫入的)
然后在域名A下有一個(gè)頁(yè)面,頁(yè)面中有很多依賴的靜態(tài)資源(都是域名A的,譬如有20個(gè)靜態(tài)資源)
此時(shí)就有一個(gè)問(wèn)題,頁(yè)面加載,請(qǐng)求這些靜態(tài)資源時(shí),瀏覽器會(huì)默認(rèn)帶上cookie
也就是說(shuō),這20個(gè)靜態(tài)資源的http請(qǐng)求,每一個(gè)都得帶上cookie,而實(shí)際上靜態(tài)資源并不需要cookie驗(yàn)證
此時(shí)就造成了較為嚴(yán)重的浪費(fèi),而且也降低了訪問(wèn)速度(因?yàn)閮?nèi)容更多了)

當(dāng)然了,針對(duì)這種場(chǎng)景,是有優(yōu)化方案的(多域名拆分)。具體做法就是:

將靜態(tài)資源分組,分別放到不同的子域名下
而子域名請(qǐng)求時(shí),是不會(huì)帶上父級(jí)域名的cookie的,所以就避免了浪費(fèi)

說(shuō)到了多域名拆分,這里再提一個(gè)問(wèn)題,那就是:

在移動(dòng)端,如果請(qǐng)求的域名數(shù)過(guò)多,會(huì)降低請(qǐng)求速度(因?yàn)橛蛎捉馕隽鞒淌呛芎馁M(fèi)時(shí)間的,而且移動(dòng)端一般帶寬都比不上pc)
此時(shí)就需要用到一種優(yōu)化方案: dns-prefetch(讓瀏覽器空閑時(shí)提前解析dns域名,不過(guò)也請(qǐng)合理使用,勿濫用)

gzip壓縮

首先,明確 gzip是一種壓縮格式,需要瀏覽器支持才有效(不過(guò)一般現(xiàn)在瀏覽器都支持),而且gzip壓縮效率很好(高達(dá)70%左右)。然后gzip一般是由 apache、 tomcat等web服務(wù)器開啟。

當(dāng)然服務(wù)器除了gzip外,也還會(huì)有其它壓縮格式(如deflate,沒(méi)有g(shù)zip高效,且不流行),所以一般只需要在服務(wù)器上開啟了gzip壓縮,然后之后的請(qǐng)求就都是基于gzip壓縮格式的,非常方便。

長(zhǎng)連接與短連接

首先看 tcp/ip層面的定義:

長(zhǎng)連接:一個(gè)tcp/ip連接上可以連續(xù)發(fā)送多個(gè)數(shù)據(jù)包,在tcp連接保持期間,如果沒(méi)有數(shù)據(jù)包發(fā)送,需要雙方發(fā)檢測(cè)包以維持此連接,一般需要自己做在線維持(類似于心跳包)
短連接:通信雙方有數(shù)據(jù)交互時(shí),就建立一個(gè)tcp連接,數(shù)據(jù)發(fā)送完成后,則斷開此tcp連接

然后在http層面:

http1.0中,默認(rèn)使用的是短連接,也就是說(shuō),瀏覽器沒(méi)進(jìn)行一次http操作,就建立一次連接,任務(wù)結(jié)束就中斷連接,譬如每一個(gè)靜態(tài)資源請(qǐng)求時(shí)都是一個(gè)多帶帶的連接
http1.1起,默認(rèn)使用長(zhǎng)連接,使用長(zhǎng)連接會(huì)有這一行 Connection:keep-alive,在長(zhǎng)連接的情況下,當(dāng)一個(gè)網(wǎng)頁(yè)打開完成后,客戶端和服務(wù)端之間用于傳輸http的tcp連接不會(huì)關(guān)閉,如果客戶端再次訪問(wèn)這個(gè)服務(wù)器的頁(yè)面,會(huì)繼續(xù)使用這一條已經(jīng)建立的連接

注意: keep-alive不會(huì)永遠(yuǎn)保持,它有一個(gè)持續(xù)時(shí)間,一般在服務(wù)器中配置(如apache),另外長(zhǎng)連接需要客戶端和服務(wù)器都支持時(shí)才有效。

http 2.0

http2.0不是https,它相當(dāng)于是http的下一代規(guī)范(譬如https的請(qǐng)求可以是http2.0規(guī)范的)。然后簡(jiǎn)述下http2.0與http1.1的顯著不同點(diǎn):

http1.1中,每請(qǐng)求一個(gè)資源,都是需要開啟一個(gè)tcp/ip連接的,所以對(duì)應(yīng)的結(jié)果是,每一個(gè)資源對(duì)應(yīng)一個(gè)tcp/ip請(qǐng)求,由于tcp/ip本身有并發(fā)數(shù)限制,所以當(dāng)資源一多,速度就顯著慢下來(lái)
http2.0中,一個(gè)tcp/ip請(qǐng)求可以請(qǐng)求多個(gè)資源,也就是說(shuō),只要一次tcp/ip請(qǐng)求,就可以請(qǐng)求若干個(gè)資源,分割成更小的幀請(qǐng)求,速度明顯提升。

所以,如果http2.0全面應(yīng)用,很多http1.1中的優(yōu)化方案就無(wú)需用到了(譬如打包成精靈圖,靜態(tài)資源多域名拆分等)。
然后簡(jiǎn)述下http2.0的一些特性:

多路復(fù)用(即一個(gè)tcp/ip連接可以請(qǐng)求多個(gè)資源)
首部壓縮(http頭部壓縮,減少體積)
二進(jìn)制分幀(在應(yīng)用層跟傳送層之間增加了一個(gè)二進(jìn)制分幀層,改進(jìn)傳輸性能,實(shí)現(xiàn)低延遲和高吞吐量)
服務(wù)器端推送(服務(wù)端可以對(duì)客戶端的一個(gè)請(qǐng)求發(fā)出多個(gè)響應(yīng),可以主動(dòng)通知客戶端)
請(qǐng)求優(yōu)先級(jí)(如果流被賦予了優(yōu)先級(jí),它就會(huì)基于這個(gè)優(yōu)先級(jí)來(lái)處理,由服務(wù)器決定需要多少資源來(lái)處理該請(qǐng)求。)

https

https就是安全版本的http,譬如一些支付等操作基本都是基于https的,因?yàn)閔ttp請(qǐng)求的安全系數(shù)太低了。

簡(jiǎn)單來(lái)看,https與http的區(qū)別就是: 在請(qǐng)求前,會(huì)建立ssl鏈接,確保接下來(lái)的通信都是加密的,無(wú)法被輕易截取分析

一般來(lái)說(shuō),如果要將網(wǎng)站升級(jí)成https,需要后端支持(后端需要申請(qǐng)證書等),然后https的開銷也比http要大(因?yàn)樾枰~外建立安全鏈接以及加密等),所以一般來(lái)說(shuō)http2.0配合https的體驗(yàn)更佳(因?yàn)閔ttp2.0更快了)

一般來(lái)說(shuō),主要關(guān)注的就是SSL/TLS的握手流程:

1.瀏覽器請(qǐng)求建立SSL鏈接,并向服務(wù)端發(fā)送一個(gè)隨機(jī)數(shù)–Client random和客戶端支持的加密方法,比如RSA加密,此時(shí)是明文傳輸。
2.服務(wù)端從中選出一組加密算法與Hash算法,回復(fù)一個(gè)隨機(jī)數(shù)–Server random,并將自己的身份信息以證書的形式發(fā)回給瀏覽器 (證書里包含了網(wǎng)站地址,非對(duì)稱加密的公鑰,以及證書頒發(fā)機(jī)構(gòu)等信息)
3.瀏覽器收到服務(wù)端的證書后
    驗(yàn)證證書的合法性(頒發(fā)機(jī)構(gòu)是否合法,證書中包含的網(wǎng)址是否和正在訪問(wèn)的一樣),如果證書信任,則瀏覽器會(huì)顯示一個(gè)小鎖頭,否則會(huì)有提示
    用戶接收證書后(不管信不信任),瀏覽會(huì)生產(chǎn)新的隨機(jī)數(shù)–Premaster secret,然后證書中的公鑰以及指定的加密方法加密 Premastersecret,發(fā)送給服務(wù)器。
    利用Client random、Server random和Premaster secret通過(guò)一定的算法生成HTTP鏈接數(shù)據(jù)傳輸?shù)膶?duì)稱加密key- session key
    使用約定好的HASH算法計(jì)算握手消息,并使用生成的 session key對(duì)消息進(jìn)行加密,最后將之前生成的所有信息發(fā)送給服務(wù)端。
4.服務(wù)端收到瀏覽器的回復(fù)
    利用已知的加解密方式與自己的私鑰進(jìn)行解密,獲取 Premastersecret
    和瀏覽器相同規(guī)則生成 session key
    使用 session key解密瀏覽器發(fā)來(lái)的握手消息,并驗(yàn)證Hash是否與瀏覽器發(fā)來(lái)的一致
    使用 session key加密一段握手消息,發(fā)送給瀏覽器
5.瀏覽器解密并計(jì)算握手消息的HASH,如果與服務(wù)端發(fā)來(lái)的HASH一致,此時(shí)握手過(guò)程結(jié)束,

之后所有的https通信數(shù)據(jù)將由之前瀏覽器生成的 session key并利用對(duì)稱加密算法進(jìn)行加密。

http的緩存

前后端的http交互中,使用緩存能很大程度上的提升效率,而且基本上對(duì)性能有要求的前端項(xiàng)目都是必用緩存的。

強(qiáng)緩存與弱緩存
緩存可以簡(jiǎn)單的劃分成兩種類型: 強(qiáng)緩存( 200fromcache)與 協(xié)商緩存( 304)
區(qū)別如下:

強(qiáng)緩存( 200fromcache)時(shí),瀏覽器如果判斷本地緩存未過(guò)期,就直接使用,無(wú)需發(fā)起http請(qǐng)求
協(xié)商緩存( 304)時(shí),瀏覽器會(huì)向服務(wù)端發(fā)起http請(qǐng)求,然后服務(wù)端告訴瀏覽器文件未改變,讓瀏覽器使用本地緩存

對(duì)于協(xié)商緩存,使用 Ctrl+F5強(qiáng)制刷新可以使得緩存無(wú)效。但是對(duì)于強(qiáng)緩存,在未過(guò)期時(shí),必須更新資源路徑才能發(fā)起新的請(qǐng)求(更改了路徑相當(dāng)于是另一個(gè)資源了,這也是前端工程化中常用到的技巧)。

緩存頭部簡(jiǎn)述
上述提到了強(qiáng)緩存和協(xié)商緩存,那它們是怎么區(qū)分的呢?答案是通過(guò)不同的http頭部控制。
緩存中常用的幾個(gè)頭部:

If-None-Match/E-tag
If-Modified-Since/Last-Modified
Cache-Control/Max-Age
Prama/Expires

屬于強(qiáng)緩存控制的:

(http1.1) Cache-Control/Max-Age
(http1.0) Pragma/Expires

注意: Max-Age不是一個(gè)頭部,它是 Cache-Control頭部的值。

屬于協(xié)商緩存控制的:

(http1.1) If-None-Match/E-tag
(http1.0) If-Modified-Since/Last-Modified

可以看到,上述有提到 http1.1和 http1.0,這些不同的頭部是屬于不同http時(shí)期的。

頭部的區(qū)別
首先明確,http的發(fā)展是從http1.0到http1.1,而在http1.1中,出了一些新內(nèi)容,彌補(bǔ)了http1.0的不足。

http1.0中的緩存控制:

Pragma:嚴(yán)格來(lái)說(shuō),它不屬于專門的緩存控制頭部,但是它設(shè)置 no-cache時(shí)可以讓本地強(qiáng)緩存失效(屬于編譯控制,來(lái)實(shí)現(xiàn)特定的指令,主要是因?yàn)榧嫒輍ttp1.0,所以以前又被大量應(yīng)用)
Expires:服務(wù)端配置的,屬于強(qiáng)緩存,用來(lái)控制在規(guī)定的時(shí)間之前,瀏覽器不會(huì)發(fā)出請(qǐng)求,而是直接使用本地緩存,注意,Expires一般對(duì)應(yīng)服務(wù)器端時(shí)間,如 Expires:Fri,30Oct199814:19:41
If-Modified-Since/Last-Modified:這兩個(gè)是成對(duì)出現(xiàn)的,屬于協(xié)商緩存的內(nèi)容,其中瀏覽器的頭部是 If-Modified-Since,而服務(wù)端的是 Last-Modified,它的作用是,在發(fā)起請(qǐng)求時(shí),如果 If-Modified-Since和 Last-Modified匹配,那么代表服務(wù)器資源并未改變,因此服務(wù)端不會(huì)返回資源實(shí)體,而是只返回頭部,通知瀏覽器可以使用本地緩存。 Last-Modified,顧名思義,指的是文件最后的修改時(shí)間,而且只能精確到 1s以內(nèi)

http1.1中的緩存控制:

Cache-Control:緩存控制頭部,有no-cache、max-age等多種取值
Max-Age:服務(wù)端配置的,用來(lái)控制強(qiáng)緩存,在規(guī)定的時(shí)間之內(nèi),瀏覽器無(wú)需發(fā)出請(qǐng)求,直接使用本地緩存,注意,Max-Age是Cache-Control頭部的值,不是獨(dú)立的頭部,譬如 Cache-Control:max-age=3600,而且它值得是絕對(duì)時(shí)間,由瀏覽器自己計(jì)算
If-None-Match/E-tag:這兩個(gè)是成對(duì)出現(xiàn)的,屬于協(xié)商緩存的內(nèi)容,其中瀏覽器的頭部是 If-None-Match,而服務(wù)端的是 E-tag,同樣,發(fā)出請(qǐng)求后,如果 If-None-Match和 E-tag匹配,則代表內(nèi)容未變,通知瀏覽器使用本地緩存,和Last-Modified不同,E-tag更精確,它是類似于指紋一樣的東西,基于 FileEtagINodeMtimeSize生成,也就是說(shuō),只要文件變,指紋就會(huì)變,而且沒(méi)有1s精確度的限制。

Max-Age相比Expires?

Expires使用的是服務(wù)器端的時(shí)間,但是有時(shí)候會(huì)有這樣一種情況-客戶端時(shí)間和服務(wù)端不同步。那這樣,可能就會(huì)出問(wèn)題了,造成了瀏覽器本地的緩存無(wú)用或者一直無(wú)法過(guò)期,所以一般http1.1后不推薦使用 Expires。而 Max-Age使用的是客戶端本地時(shí)間的計(jì)算,因此不會(huì)有這個(gè)問(wèn)題,因此推薦使用 Max-Age。

注意,如果同時(shí)啟用了 Cache-Control與 Expires, Cache-Control優(yōu)先級(jí)高。

E-tag相比Last-Modified?

Last-Modified:
    表明服務(wù)端的文件最后何時(shí)改變的
    它有一個(gè)缺陷就是只能精確到1s,
    然后還有一個(gè)問(wèn)題就是有的服務(wù)端的文件會(huì)周期性的改變,導(dǎo)致緩存失效
E-tag:
    是一種指紋機(jī)制,代表文件相關(guān)指紋
    只有文件變才會(huì)變,也只要文件變就會(huì)變,
    也沒(méi)有精確時(shí)間的限制,只要文件一遍,立馬E-tag就不一樣了
    如果同時(shí)帶有 E-tag和 Last-Modified,服務(wù)端會(huì)優(yōu)先檢查 E-tag。
6. 瀏覽器接收到http數(shù)據(jù)包后的解析流程

渲染流程大致如下:

1.解析HTML,構(gòu)建DOM樹
2.解析CSS,生成CSS規(guī)則樹
3.合并DOM樹和CSS規(guī)則,生成render樹
4.布局render樹(Layout/reflow),負(fù)責(zé)各元素尺寸、位置的計(jì)算
5.繪制render樹(paint),繪制頁(yè)面像素信息
6.瀏覽器會(huì)將各層的信息發(fā)送給GPU,GPU會(huì)將各層合成(composite),顯示在屏幕上

找了個(gè)圖:

HTML解析,構(gòu)建DOM

整個(gè)渲染步驟中,HTML解析是第一步。簡(jiǎn)單的理解,這一步的流程是這樣的:瀏覽器解析HTML,構(gòu)建DOM樹。

Bytes → characters → tokens → nodes → DOM
假設(shè)有下面這樣一個(gè)代碼

  
        
        
        
        Critical Path
    
        
        

Helloweb performance students!

瀏覽器的處理如下:

列舉其中的一些重點(diǎn)過(guò)程:

Conversion轉(zhuǎn)換:瀏覽器將獲得的HTML內(nèi)容(Bytes)基于他的編碼轉(zhuǎn)換為單個(gè)字符
Tokenizing分詞:瀏覽器按照HTML規(guī)范標(biāo)準(zhǔn)將這些字符轉(zhuǎn)換為不同的標(biāo)記token。每個(gè)token都有自己獨(dú)特的含義以及規(guī)則集
Lexing詞法分析:分詞的結(jié)果是得到一堆的token,此時(shí)把他們轉(zhuǎn)換為對(duì)象,這些對(duì)象分別定義他們的屬性和規(guī)則
DOM構(gòu)建:因?yàn)镠TML標(biāo)記定義的就是不同標(biāo)簽之間的關(guān)系,這個(gè)關(guān)系就像是一個(gè)樹形結(jié)構(gòu)一樣。例如:body對(duì)象的父節(jié)點(diǎn)就是HTML對(duì)象,然后段略p對(duì)象的父節(jié)點(diǎn)就是body對(duì)象

最后的DOM樹如下:

生成CSS規(guī)則
Bytes → characters → tokens → nodes → CSSOM
有如下css代碼:

body { font-size: 16px }
p { font-weight: bold }
span { color: red}
p span { display: none }
img { float: right }

cssom樹:

當(dāng)DOM樹和CSSOM都有了后,就要開始構(gòu)建渲染樹了。

然后從渲染樹開始生成我們看到的html頁(yè)面。
在這個(gè)過(guò)程中又一個(gè)小問(wèn)題,重新構(gòu)建和渲染頁(yè)面:

重新構(gòu)建,也稱為Reflow,即回流。一般意味著元素的內(nèi)容、結(jié)構(gòu)、位置或尺寸發(fā)生了變化,需要重新計(jì)算樣式和渲染樹
渲染頁(yè)面,也稱為Repaint,即重繪。意味著元素發(fā)生的改變只是影響了元素的一些外觀之類的時(shí)候(例如,背景色,邊框顏色,文字顏色等),此時(shí)只需要應(yīng)用新樣式繪制這個(gè)元素就可以了

回流的成本開銷要高于重繪,而且一個(gè)節(jié)點(diǎn)的回流往往回導(dǎo)致子節(jié)點(diǎn)以及同級(jí)節(jié)點(diǎn)的回流,所以優(yōu)化方案中一般都包括,盡量避免回流。

什么會(huì)引起回流?
1.頁(yè)面渲染初始化
2.DOM結(jié)構(gòu)改變,比如刪除了某個(gè)節(jié)點(diǎn)
3.render樹變化,比如減少了padding
4.窗口resize
5.最復(fù)雜的一種:獲取某些屬性,引發(fā)回流

很多瀏覽器會(huì)對(duì)回流做優(yōu)化,會(huì)等到數(shù)量足夠時(shí)做一次批處理回流,但是除了render樹的直接變化,當(dāng)獲取一些屬性時(shí),瀏覽器為了獲得正確的值也會(huì)觸發(fā)回流,這樣使得瀏覽器優(yōu)化無(wú)效,包括:

1.offset(Top/Left/Width/Height)
2.scroll(Top/Left/Width/Height)
3.cilent(Top/Left/Width/Height)
4.width,height
5.調(diào)用了getComputedStyle()或者IE的currentStyle

回流一定伴隨著重繪,重繪卻可以多帶帶出現(xiàn)。所以一般會(huì)有一些優(yōu)化方案,如:

1.減少逐項(xiàng)更改樣式,最好一次性更改style,或者將樣式定義為class并一次性更新
2.避免循環(huán)操作dom,創(chuàng)建一個(gè)documentFragment或div,在它上面應(yīng)用所有DOM操作,最后再把它添加到window.document
3.避免多次讀取offset等屬性。無(wú)法避免則將它們緩存到變量
4.將復(fù)雜的元素絕對(duì)定位或固定定位,使得它脫離文檔流,否則回流代價(jià)會(huì)很高

注意:改變字體大小會(huì)引發(fā)回流

var s = document.body.style;
s.padding = "2px";    // 回流+重繪
s.border = "1px solid red";    // 再一次 回流+重繪
s.color = "blue";    // 再一次重繪
s.backgroundColor = "#ccc";    // 再一次 重繪
s.fontSize = "14px";    // 再一次 回流+重繪
// 添加node,再一次 回流+重繪
document.body.appendChild(document.createTextNode("abc!"));

資源外鏈的下載

上面介紹了html解析,渲染流程。但實(shí)際上,在解析html時(shí),會(huì)遇到一些資源連接,此時(shí)就需要進(jìn)行多帶帶處理了。簡(jiǎn)單起見(jiàn),這里將遇到的靜態(tài)資源分為一下幾大類(未列舉所有):

CSS樣式資源
JS腳本資源
img圖片類資源
遇到外鏈時(shí)的處理

當(dāng)遇到上述的外鏈時(shí),會(huì)多帶帶開啟一個(gè)下載線程去下載資源(http1.1中是每一個(gè)資源的下載都要開啟一個(gè)http請(qǐng)求,對(duì)應(yīng)一個(gè)tcp/ip鏈接)。

遇到CSS樣式資源

CSS資源的處理有幾個(gè)特點(diǎn):

CSS下載時(shí)異步,不會(huì)阻塞瀏覽器構(gòu)建DOM樹
但是會(huì)阻塞渲染,也就是在構(gòu)建render時(shí),會(huì)等到css下載解析完畢后才進(jìn)行(這點(diǎn)與瀏覽器優(yōu)化有關(guān),防止css規(guī)則不斷改變,避免了重復(fù)的構(gòu)建)

有例外, media query聲明的CSS是不會(huì)阻塞渲染的

遇到JS腳本資源

JS腳本資源的處理有幾個(gè)特點(diǎn):

阻塞瀏覽器的解析,也就是說(shuō)發(fā)現(xiàn)一個(gè)外鏈腳本時(shí),需等待腳本下載完成并執(zhí)行后才會(huì)繼續(xù)解析HTML
瀏覽器的優(yōu)化,一般現(xiàn)代瀏覽器有優(yōu)化,在腳本阻塞時(shí),也會(huì)繼續(xù)下載其它資源(當(dāng)然有并發(fā)上限),但是雖然腳本可以并行下載,解析過(guò)程仍然是阻塞的,也就是說(shuō)必須這個(gè)腳本執(zhí)行完畢后才會(huì)接下來(lái)的解析,并行下載只是一種優(yōu)化而已
defer與async,普通的腳本是會(huì)阻塞瀏覽器解析的,但是可以加上defer或async屬性,這樣腳本就變成異步了,可以等到解析完畢后再執(zhí)行

注意,defer和async是有區(qū)別的: defer是延遲執(zhí)行,而async是異步執(zhí)行。

簡(jiǎn)單的說(shuō)(不展開):

async是異步執(zhí)行,異步下載完畢后就會(huì)執(zhí)行,不確保執(zhí)行順序,一定在 onload前,但不確定在 DOMContentLoaded事件的前或后
defer是延遲執(zhí)行,在瀏覽器看起來(lái)的效果像是將腳本放在了 body后面一樣(雖然按規(guī)范應(yīng)該是在 DOMContentLoaded事件前,但實(shí)際上不同瀏覽器的優(yōu)化效果不一樣,也有可能在它后面)

遇到img圖片類資源

遇到圖片等資源時(shí),直接就是異步下載,不會(huì)阻塞解析,下載完畢后直接用圖片替換原有src的地方。

loaded和domcontentloaded

簡(jiǎn)單的對(duì)比:

DOMContentLoaded 事件觸發(fā)時(shí),僅當(dāng)DOM加載完成,不包括樣式表,圖片(譬如如果有async加載的腳本就不一定完成)
load 事件觸發(fā)時(shí),頁(yè)面上所有的DOM,樣式表,腳本,圖片都已經(jīng)加載完成了
7. CSS的可視化格式模型

html元素按什么規(guī)則渲染,接下來(lái)提到的內(nèi)容來(lái)揭曉

CSS中規(guī)定每一個(gè)元素都有自己的盒子模型(相當(dāng)于規(guī)定了這個(gè)元素如何顯示)
然后可視化格式模型則是把這些盒子按照規(guī)則擺放到頁(yè)面上,也就是如何布局
換句話說(shuō),盒子模型規(guī)定了怎么在頁(yè)面里擺放盒子,盒子的相互作用等等

說(shuō)到底: CSS的可視化格式模型就是規(guī)定了瀏覽器在頁(yè)面中如何處理文檔樹。
關(guān)鍵字:

包含塊(Containing Block)
控制框(Controlling Box)
BFC(Block Formatting Context)
IFC(Inline Formatting Context)
定位體系
浮動(dòng)

CSS有三種定位機(jī)制: 普通流, 浮動(dòng), 絕對(duì)定位

包含塊(Containing Block)

一個(gè)元素的box的定位和尺寸,會(huì)與某一矩形框有關(guān),這個(gè)框就稱之為包含塊。元素會(huì)為它的子孫元素創(chuàng)建包含塊,但是,并不是說(shuō)元素的包含塊就是它的父元素,元素的包含塊與它的祖先元素的樣式等有關(guān)系。

比如:

根元素是最頂端的元素,它沒(méi)有父節(jié)點(diǎn),它的包含塊就是初始包含塊
static和relative的包含塊由它最近的塊級(jí)、單元格或者行內(nèi)塊祖先元素的內(nèi)容框(content)創(chuàng)建
fixed的包含塊是當(dāng)前可視窗口
absolute的包含塊由它最近的position 屬性為 absolute、 relative或者 fixed的祖先元素創(chuàng)建
    如果其祖先元素是行內(nèi)元素,則包含塊取決于其祖先元素的 direction特性
    如果祖先元素不是行內(nèi)元素,那么包含塊的區(qū)域應(yīng)該是祖先元素的內(nèi)邊距邊界
    

控制框(Controlling Box)

塊級(jí)元素和塊框以及行內(nèi)元素和行框的相關(guān)概念
塊框:

塊級(jí)元素會(huì)生成一個(gè)塊框( BlockBox),塊框會(huì)占據(jù)一整行,用來(lái)包含子box和生成的內(nèi)容
塊框同時(shí)也是一個(gè)塊包含框( ContainingBox),里面要么只包含塊框,要么只包含行內(nèi)框(不能混雜),如果塊框內(nèi)部有塊級(jí)元素也有行內(nèi)元素,那么行內(nèi)元素會(huì)被匿名塊框包圍

如果一個(gè)塊框在其中包含另外一個(gè)塊框,那么我們強(qiáng)迫它只能包含塊框,因此其它文本內(nèi)容生成出來(lái)的都是匿名塊框(而不是匿名行內(nèi)框)。

行內(nèi)框:

一個(gè)行內(nèi)元素生成一個(gè)行內(nèi)框
行內(nèi)元素能排在一行,允許左右有其它元素

display的幾個(gè)屬性也可以影響不同框的生成:

block,元素生成一個(gè)塊框
inline,元素產(chǎn)生一個(gè)或多個(gè)的行內(nèi)框
inline-block,元素產(chǎn)生一個(gè)行內(nèi)級(jí)塊框,行內(nèi)塊框的內(nèi)部會(huì)被當(dāng)作塊塊來(lái)格式化,而此元素本身會(huì)被當(dāng)作行內(nèi)級(jí)框來(lái)格式化(這也是為什么會(huì)產(chǎn)生 BFC)
none,不生成框,不再格式化結(jié)構(gòu)中,當(dāng)然了,另一個(gè) visibility:hidden則會(huì)產(chǎn)生一個(gè)不可見(jiàn)的框

BFC(Block Formatting Context)

FC即格式上下文,它定義框內(nèi)部的元素渲染規(guī)則,比較抽象,比如:

FC像是一個(gè)大箱子,里面裝有很多元素
箱子可以隔開里面的元素和外面的元素(所以外部并不會(huì)影響FC內(nèi)部的渲染)
內(nèi)部的規(guī)則可以是:如何定位,寬高計(jì)算,margin折疊等等
不同類型的框參與的FC類型不同,譬如塊級(jí)框?qū)?yīng)BFC,行內(nèi)框?qū)?yīng)IFC。

注意,并不是說(shuō)所有的框都會(huì)產(chǎn)生FC,而是符合特定條件才會(huì)產(chǎn)生,只有產(chǎn)生了對(duì)應(yīng)的FC后才會(huì)應(yīng)用對(duì)應(yīng)渲染規(guī)則。

BFC規(guī)則:

在塊格式化上下文中,每一個(gè)元素左外邊與包含塊的左邊相接觸(對(duì)于從右到左的格式化,右外邊接觸右邊),即使存在浮動(dòng)也是如此(所以浮動(dòng)元素正常會(huì)直接貼近它的包含塊的左邊,與普通元素重合),除非這個(gè)元素也創(chuàng)建了一個(gè)新的BFC。

總結(jié)幾點(diǎn)BFC特點(diǎn):

內(nèi)部 box在垂直方向,一個(gè)接一個(gè)的放置
box的垂直方向由 margin決定,屬于同一個(gè)BFC的兩個(gè)box間的margin會(huì)重疊
BFC區(qū)域不會(huì)與 floatbox重疊(可用于排版)
BFC就是頁(yè)面上的一個(gè)隔離的獨(dú)立容器,容器里面的子元素不會(huì)影響到外面的元素。反之也如此
計(jì)算BFC的高度時(shí),浮動(dòng)元素也參與計(jì)算(不會(huì)浮動(dòng)坍塌)

如何觸發(fā)BFC?

根元素
float屬性不為 none
position為 absolute或 fixed
display為 inline-block, flex, inline-flex, table, table-cell, table-caption
overflow不為 visible

這里提下, display:table,它本身不產(chǎn)生BFC,但是它會(huì)產(chǎn)生匿名框(包含 display:table-cell的框)。

IFC(Inline Formatting Context)

IFC即行內(nèi)框產(chǎn)生的格式上下文。

IFC規(guī)則

在行內(nèi)格式化上下文中,框一個(gè)接一個(gè)地水平排列,起點(diǎn)是包含塊的頂部。水平方向上的 margin,border 和 padding 在框之間得到保留,框在垂直方向上可以以不同的方式對(duì)齊:它們的頂部或底部對(duì)齊,或根據(jù)其中文字的基線對(duì)齊。

行框

包含那些框的長(zhǎng)方形區(qū)域,會(huì)形成一行,叫做行框。行框的寬度由它的包含塊和其中的浮動(dòng)元素決定,高度的確定由行高度計(jì)算規(guī)則決定。

行框的規(guī)則:

如果幾個(gè)行內(nèi)框在水平方向無(wú)法放入一個(gè)行框內(nèi),它們可以分配在兩個(gè)或多個(gè)垂直堆疊的行框中(即行內(nèi)框的分割)
行框在堆疊時(shí)沒(méi)有垂直方向上的分割且永不重疊
行框的高度總是足夠容納所包含的所有框。不過(guò),它可能高于它包含的最高的框(例如,框?qū)R會(huì)引起基線對(duì)齊)
行框的左邊接觸到其包含塊的左邊,右邊接觸到其包含塊的右邊

結(jié)合補(bǔ)充下IFC規(guī)則

浮動(dòng)元素可能會(huì)處于包含塊邊緣和行框邊緣之間,盡管在相同的行內(nèi)格式化上下文中的行框通常擁有相同的寬度(包含塊的寬度),它們可能會(huì)因浮動(dòng)元素縮短了可用寬度,而在寬度上發(fā)生變化。

同一行內(nèi)格式化上下文中的行框通常高度不一樣(如,一行包含了一個(gè)高的圖形,而其它行只包含文本),當(dāng)一行中行內(nèi)框?qū)挾鹊目偤托∮诎鼈兊男锌虻膶?,它們?cè)谒椒较蛏系膶?duì)齊,取決于 text-align 特性??盏男袃?nèi)框應(yīng)該被忽略。

即不包含文本,保留空白符,margin/padding/border非0的行內(nèi)元素,以及其他常規(guī)流中的內(nèi)容(比如,圖片,inline blocks 和 inline tables),并且不是以換行結(jié)束的行框,必須被當(dāng)作零高度行框?qū)Υ?/p>

總結(jié):

行內(nèi)元素總是會(huì)應(yīng)用IFC渲染規(guī)則
行內(nèi)元素會(huì)應(yīng)用IFC規(guī)則渲染,譬如 text-align可以用來(lái)居中等
塊框內(nèi)部,對(duì)于文本這類的匿名元素,會(huì)產(chǎn)生匿名行框包圍,而行框內(nèi)部就應(yīng)用IFC渲染規(guī)則
行內(nèi)框內(nèi)部,對(duì)于那些行內(nèi)元素,一樣應(yīng)用IFC渲染規(guī)則
另外, inline-block,會(huì)在元素外層產(chǎn)生IFC(所以這個(gè)元素是可以通過(guò) text-align水平居中的),當(dāng)然,它內(nèi)部則按照BFC規(guī)則渲染

相比BFC規(guī)則來(lái)說(shuō),IFC可能更加抽象(因?yàn)闆](méi)有那么條理清晰的規(guī)則和觸發(fā)條件),但總的來(lái)說(shuō),它就是行內(nèi)元素自身如何顯示以及在框內(nèi)如何擺放的渲染規(guī)則,這樣描述應(yīng)該更容易理解。

關(guān)于css的一些別的規(guī)則,大家可以去搜搜:

如常規(guī)流,浮動(dòng),絕對(duì)定位等區(qū)別
如浮動(dòng)元素不包含在常規(guī)流中
如相對(duì)定位,絕對(duì)定位, Fixed定位等區(qū)別
如 z-index的分層顯示機(jī)制等
8. JS引擎解析過(guò)程

這個(gè)部分的內(nèi)容請(qǐng)參考這兒:JS引擎解析過(guò)程
直接略過(guò)了

9. 跨域、web安全

跨域

為什么會(huì)跨域:

在瀏覽器同源策略限制下,向不同源(不同協(xié)議、不同域名或者不同端口)發(fā)送XHR請(qǐng)求,瀏覽器認(rèn)為該請(qǐng)求不受信任,禁止請(qǐng)求,具體表現(xiàn)為請(qǐng)求后不正常響應(yīng)

舉個(gè)栗子:

那要怎么搞呢?網(wǎng)上的解決辦法也很多,這兒列一些:

1.jsonp
2.cors
3.document.domain
4.POSTmessage

想深入看的可以瀏覽一下這個(gè) 跨域的常用解決方式

web安全

這個(gè)東西,我們?cè)诿嬖嚨臅r(shí)候肯定會(huì)被問(wèn)到xss攻擊的問(wèn)題,大家自行搜索把,這個(gè)問(wèn)題的解決方案也超級(jí)多,官方文檔也介紹很詳細(xì),這兒就不整了

參考:參考文章

有大佬也總結(jié)過(guò)了很詳細(xì)的內(nèi)容,我照搬了點(diǎn)兒內(nèi)容,勿噴,只是學(xué)習(xí)一下。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99329.html

相關(guān)文章

  • 輸入URL覽器顯示頁(yè)過(guò)程搜集各方資料總結(jié)一下

    摘要:通用頭部這也是開發(fā)人員見(jiàn)過(guò)的最多的信息,包括如下請(qǐng)求的服務(wù)器地址請(qǐng)求方式請(qǐng)求的返回狀態(tài)碼,如代表成功請(qǐng)求的遠(yuǎn)程服務(wù)器地址會(huì)轉(zhuǎn)為譬如,在跨域拒絕時(shí),可能是為,狀態(tài)碼為等當(dāng)然,實(shí)際上可能的組合有很多。 面試中經(jīng)常會(huì)被問(wèn)到這個(gè)問(wèn)題吧,唉,我最開始被問(wèn)到的時(shí)候也就能大概說(shuō)一些流程。被問(wèn)得多了,自己就想去找找這個(gè)問(wèn)題的全面回答,于是乎搜了很多資料和網(wǎng)上的文章,根據(jù)那些文章寫一個(gè)總結(jié)。 寫得不好...

    RobinTang 評(píng)論0 收藏0
  • 輸入URL覽器顯示頁(yè)過(guò)程,搜集各方資料總結(jié)一下

    摘要:通用頭部這也是開發(fā)人員見(jiàn)過(guò)的最多的信息,包括如下請(qǐng)求的服務(wù)器地址請(qǐng)求方式請(qǐng)求的返回狀態(tài)碼,如代表成功請(qǐng)求的遠(yuǎn)程服務(wù)器地址會(huì)轉(zhuǎn)為譬如,在跨域拒絕時(shí),可能是為,狀態(tài)碼為等當(dāng)然,實(shí)際上可能的組合有很多。 面試中經(jīng)常會(huì)被問(wèn)到這個(gè)問(wèn)題吧,唉,我最開始被問(wèn)到的時(shí)候也就能大概說(shuō)一些流程。被問(wèn)得多了,自己就想去找找這個(gè)問(wèn)題的全面回答,于是乎搜了很多資料和網(wǎng)上的文章,根據(jù)那些文章寫一個(gè)總結(jié)。 寫得不好...

    BingqiChen 評(píng)論0 收藏0
  • 干貨 | 學(xué)習(xí)Python正確姿勢(shì)

    摘要:勤學(xué)學(xué)習(xí)效率與效果取決于執(zhí)行力。這一步學(xué)習(xí)的正確姿勢(shì)是在實(shí)踐操作中發(fā)掘問(wèn)題,然后帶著問(wèn)題找答案。拆分任務(wù)將目標(biāo)分解成具體可執(zhí)行的學(xué)習(xí)任務(wù)。勤學(xué)強(qiáng)大的執(zhí)行力是學(xué)習(xí)的根本保障。分享復(fù)述檢驗(yàn)學(xué)習(xí)成果,提高學(xué)習(xí)效果的最好方法。 showImg(https://segmentfault.com/img/bVbcPGZ?w=256&h=256); 前段時(shí)間和大家一起分享了一篇關(guān)于學(xué)習(xí)方法內(nèi)容《大牛...

    Thanatos 評(píng)論0 收藏0
  • 我是如何學(xué)習(xí)小程序

    摘要:行勝于言,理論結(jié)合實(shí)踐才是王道,所以本文我將基于前面的學(xué)習(xí)方法,分享我是如何學(xué)習(xí)微信小程序的。第二個(gè)目標(biāo)則需要學(xué)習(xí)小程序的插件相關(guān)接口調(diào)用,以及蟬知建站系統(tǒng)這邊的微信模塊代碼。 前段時(shí)間和大家一起分享了一篇關(guān)于學(xué)習(xí)方法內(nèi)容《大牛與搬運(yùn)工的差距——學(xué)習(xí)方法的力量》。我們將學(xué)習(xí)過(guò)程分成八步,并借鑒了敏捷開發(fā)的迭代思想,以達(dá)到自我迭代學(xué)習(xí)的效果。行勝于言,理論結(jié)合實(shí)踐才是王道,所以本文我將基...

    XGBCCC 評(píng)論0 收藏0
  • 干貨 | PHP就該這么學(xué)!

    摘要:梳理之后,目標(biāo)就會(huì)被分解成一個(gè)個(gè)需要完成的具體任務(wù)。勤學(xué)學(xué)習(xí)效率與效果取決于執(zhí)行力。這種選手即便幫他解決了問(wèn)題,他也學(xué)不到東西。拆分任務(wù)將目標(biāo)分解成具體可執(zhí)行的學(xué)習(xí)任務(wù)。搜集知識(shí)資源查閱官方文檔購(gòu)買書籍搜集網(wǎng)絡(luò)干貨文章。 前段時(shí)間和大家一起分享了一篇關(guān)于學(xué)習(xí)方法內(nèi)容《大牛與搬運(yùn)工的差距——學(xué)習(xí)方法的力量》。我們將學(xué)習(xí)過(guò)程分成八步,并借鑒了敏捷開發(fā)的迭代思想,以達(dá)到自我迭代學(xué)習(xí)的效果。行...

    wushuiyong 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<