Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
http0.9流程:
客戶端,構(gòu)建請(qǐng)求,通過(guò)DNS查詢IP地址,三次握手建立TCP連接,客戶端發(fā)起請(qǐng)求,服務(wù)器響應(yīng),四次揮手,斷開(kāi)TCP連接。(與服務(wù)器只有一個(gè)來(lái)回)
http1.0流程:
客戶端,構(gòu)建請(qǐng)求,通過(guò)DNS查詢IP地址,三次握手建立TCP連接,客戶端發(fā)起請(qǐng)求,服務(wù)器響應(yīng),四次揮手,斷開(kāi)TCP連接。(與服務(wù)器有兩個(gè)來(lái)回)
因?yàn)椴蛔闳毕荩陀辛薶ttp1.1。
http1.1中瀏覽器再也不用為每個(gè)請(qǐng)求重新發(fā)起TCP連接了,增加內(nèi)容有:緩存相關(guān)首部的擴(kuò)展,OPTIONS方法,Upgrade首部,Range請(qǐng)求,壓縮和傳輸編碼,管道化等。但還是滿足不了現(xiàn)在的web發(fā)展需求,so,就有了http.2版本。
http2解決了(管道化特性可以讓客戶端一次發(fā)送所有的請(qǐng)求,但是有些問(wèn)題阻礙了管道化的發(fā)展,即使某個(gè)請(qǐng)求花了很長(zhǎng)時(shí)間,那么隊(duì)頭阻塞會(huì)影響其他請(qǐng)求。)http中的隊(duì)頭阻塞問(wèn)題。
使用http2會(huì)比http1.1在使用TCP時(shí),用戶體驗(yàn)的感知多數(shù)延遲的效果有了量化的改善,以及提升了TCP連接的利用率(并行的實(shí)現(xiàn)機(jī)制不依賴與服務(wù)器建立多個(gè)連接)
所以需要學(xué)習(xí)http2,了解更過(guò)的內(nèi)容來(lái)掌握計(jì)算機(jī)網(wǎng)絡(luò)。
對(duì)于http2,你可以來(lái)運(yùn)行一個(gè)http2的服務(wù)器,獲取并安裝一個(gè)http2的web服務(wù)器,下載并安裝一張TLS證書(shū),讓瀏覽器和服務(wù)器通過(guò)http2來(lái)連接。(從數(shù)字證書(shū)認(rèn)證機(jī)構(gòu)申請(qǐng)一張證書(shū))。
了解http2的協(xié)議,先讓我們了解一下web頁(yè)面的請(qǐng)求,就是用戶在瀏覽器中呈現(xiàn)的效果,發(fā)生了些什么呢?
資源獲取的步驟:
把待請(qǐng)求URL放入隊(duì)列,判斷URL是否已在請(qǐng)求隊(duì)列,否的話就結(jié)束,是的話就判斷請(qǐng)求域名是否DNS緩存中,沒(méi)有的話就解析域名,有的話就到指定域名的TCP連接是否開(kāi)啟,沒(méi)有的話就開(kāi)啟TCP連接,進(jìn)行HTTPS請(qǐng)求,初始化并完成TLS協(xié)議握手,向頁(yè)面對(duì)應(yīng)的URL發(fā)送請(qǐng)求。
接收響應(yīng)以及頁(yè)面渲染步驟:
接收請(qǐng)求,判斷是否HTML頁(yè)面,是就解析HTML,對(duì)頁(yè)面引用資源排優(yōu)先級(jí),添加引用資源到請(qǐng)求隊(duì)列。(如果頁(yè)面上的關(guān)鍵資源已經(jīng)接收到,就開(kāi)始渲染頁(yè)面),判斷是否有還要繼續(xù)接收資源,繼續(xù)解析渲染,直到結(jié)束。
第一種GET方法:發(fā)送一個(gè)請(qǐng)求來(lái)獲取服務(wù)器上的某一些資源。
第二種POST方法:向URL指定的資源提交數(shù)據(jù)或附加新的數(shù)據(jù)。
第三種PUT方法:跟POST方法一樣,可以向服務(wù)器提交數(shù)據(jù),但是它們之間也所有不同,PUT指定了資源在服務(wù)器的位置,而POST沒(méi)有哦。
第四種HEAD方法:指請(qǐng)求頁(yè)面的首部。
第五種DELETE方法:刪除服務(wù)器上的某資源。
第六種OPTIONS方法:它用于獲取當(dāng)前URL所支持的方法,如果請(qǐng)求成功,在Allow的頭包含類似GET,POST等的信息。
第七種TARCE方法:用于激發(fā)一個(gè)遠(yuǎn)程的,應(yīng)用層的請(qǐng)求消息回路。
第八種CONNECT方法:把請(qǐng)求連接轉(zhuǎn)換到TCP/TP通道。
簡(jiǎn)單說(shuō)說(shuō),瀏覽器根據(jù)請(qǐng)求的url交給dns域名解析,查找真正的ip地址,向服務(wù)器發(fā)起請(qǐng)求;服務(wù)器交給后臺(tái)處理后,返回?cái)?shù)據(jù),瀏覽器會(huì)接收到文件數(shù)據(jù),比如,html,js,css,圖像等;然后瀏覽器會(huì)對(duì)加載到的資源進(jìn)行語(yǔ)法解析,建立相應(yīng)的內(nèi)部數(shù)據(jù)結(jié)構(gòu);載入解析到的資源文件,渲染頁(yè)面,完成顯示頁(yè)面效果。
不夠清楚明白碼?
那就再次詳細(xì)一下,咳咳,從瀏覽器接收url,開(kāi)始進(jìn)行網(wǎng)絡(luò)請(qǐng)求線程,發(fā)出一個(gè)完整的HTTP請(qǐng)求,從服務(wù)器端接收請(qǐng)求到對(duì)應(yīng)的后臺(tái)接收到請(qǐng)求,然后是后臺(tái)和前臺(tái)的http交互;其中的緩存問(wèn)題(http的緩存),瀏覽器接收到http數(shù)據(jù)包后的解析流程,css的可視化格式模型,js引擎解析過(guò)程等;其他呈現(xiàn)頁(yè)面效果。
:這里就需要你對(duì)瀏覽器內(nèi)核的理解:其中主要的渲染引擎和JS引擎,這里了解一下你對(duì)瀏覽器內(nèi)核的理解。
瀏覽器的內(nèi)核的不同對(duì)于網(wǎng)頁(yè)的語(yǔ)法解釋會(huì)有不同,所以渲染的效果也不相同。其實(shí)最開(kāi)始渲染引擎和JS引擎是沒(méi)有區(qū)分明確的,不過(guò)后來(lái)JS引擎越來(lái)越獨(dú)立,so,內(nèi)核就傾向于渲染引擎。
對(duì)于資源請(qǐng)求/獲取,資源響應(yīng)/頁(yè)面渲染,會(huì)給網(wǎng)絡(luò)帶寬和設(shè)備資源帶來(lái)壓力,這個(gè)時(shí)候就會(huì)考慮到web的性能優(yōu)化。
其中里面的性能關(guān)鍵:
什么是數(shù)據(jù)包 數(shù)據(jù)包(IP數(shù)據(jù)包),指封裝在固定結(jié)構(gòu)的一系列字節(jié),它定義了數(shù)據(jù)包的長(zhǎng)度,傳輸?shù)募?xì)節(jié),以及其他與TCP相關(guān)的信息。
延遲:指IP數(shù)據(jù)包從一個(gè)網(wǎng)絡(luò)端點(diǎn)到另一個(gè)網(wǎng)絡(luò)端點(diǎn)所花費(fèi)的時(shí)間。(所花費(fèi)時(shí)間在于往返時(shí)延,是延遲的時(shí)間的兩倍)
帶寬:只要帶寬沒(méi)有飽和,兩個(gè)網(wǎng)絡(luò)端點(diǎn)的連接會(huì)一次處理盡可能多的數(shù)據(jù)量(所以帶寬可能會(huì)成為性能的瓶頸)
建立連接時(shí)間:在客戶端和服務(wù)器之間建立連接往返數(shù)據(jù)(三次握手)
TCP三次握手過(guò)程:客戶端向服務(wù)器發(fā)起一個(gè)SYN包,服務(wù)器端返回對(duì)應(yīng)的SYN的ACK響應(yīng)以及新的SYN包,然后客戶端返回對(duì)應(yīng)的ACK。(在客戶端和服務(wù)器之間建立正常的TCP網(wǎng)絡(luò)連接時(shí),客戶端首先發(fā)出一個(gè)SYN消息,服務(wù)器使用SYN+ACK應(yīng)答表示接收了這個(gè)消息,最后客戶端再以ACK消息響應(yīng)。)
SYN是同步序列編號(hào),是TCP/IP建立連接時(shí)使用的握手信息。ACK是確認(rèn)字符,在數(shù)據(jù)通信中,接收站發(fā)給發(fā)送站的一種傳輸類控制字符。表示發(fā)來(lái)的數(shù)據(jù)已確認(rèn)接收無(wú)誤。在TCP/IP協(xié)議中,如果接收方成功的接收到數(shù)據(jù),那么會(huì)回復(fù)一個(gè)ACK數(shù)據(jù)。通過(guò)ACK信號(hào)有自己固定的格式,長(zhǎng)度大小,由接收方回復(fù)給發(fā)送方。
詳解三次握手:
第一次握手,建立連接時(shí),客戶端發(fā)送SYN包到服務(wù)器,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn),其中SYN就是同步序列編號(hào)。
第二次握手,服務(wù)器收到SYN包,必須確認(rèn)客戶的SYN,同時(shí)自己也發(fā)送一個(gè)SYN包,即是SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài)。
第三次握手,客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK,此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。
完成三次握手,客戶端與服務(wù)器開(kāi)始傳送數(shù)據(jù)。
TLS協(xié)商時(shí)間(TLS會(huì)造成額外的往返傳輸)
除了網(wǎng)絡(luò),還有頁(yè)面內(nèi)容本身或服務(wù)器性能,如首字節(jié)時(shí)間TTFB,內(nèi)容下載時(shí)間,開(kāi)始渲染時(shí)間,文檔加載完成的時(shí)間等。
那么什么是TTFB,它是指客戶端從開(kāi)始定位到web頁(yè)面,直接收到主體頁(yè)面響應(yīng)的第一字節(jié)所耗費(fèi)的時(shí)間。它是測(cè)量:從瀏覽器發(fā)起請(qǐng)求至收到其第一字節(jié)之間的耗時(shí)。
內(nèi)容下載時(shí)間是等同于被請(qǐng)求資源的最后字節(jié)到達(dá)時(shí)間。
開(kāi)始渲染時(shí)間,從客戶看到空白頁(yè)面的時(shí)長(zhǎng)。
優(yōu)化技術(shù):
對(duì)于http1的問(wèn)題,迎來(lái)了http2。其中http1的問(wèn)題:
隊(duì)頭阻塞,大多數(shù)情況下,瀏覽器會(huì)希望同時(shí)獲取許多資源,但http1未提供機(jī)制來(lái)同時(shí)請(qǐng)求這些資源,如果僅是使用一個(gè)連接,需要發(fā)起請(qǐng)求,等待響應(yīng),然后才能發(fā)起下一個(gè)請(qǐng)求。
在http1中要給特性為管道化,可以允許一次發(fā)送一組請(qǐng)求,但是需要按照發(fā)送順序依次接收響應(yīng)。所以在請(qǐng)求應(yīng)答過(guò)程中,如發(fā)生什么情況,剩下的工作都會(huì)被阻塞,這就是“隊(duì)頭阻塞”(阻塞在那次請(qǐng)求應(yīng)答發(fā)生錯(cuò)誤),阻礙網(wǎng)絡(luò)傳輸和web頁(yè)面的渲染,指導(dǎo)失去響應(yīng)。
低效的TCP利用,TCP協(xié)議作為最可靠的協(xié)議之一,其核心是擁塞窗口。
擁塞窗口,是衛(wèi)星通信在因特網(wǎng)中防止通信擁塞的一種措施,它是在發(fā)端采用了一種“擁塞避免”算法和“慢速啟動(dòng)”算法相結(jié)合的機(jī)制。“擁塞窗口”就是“擁塞避免”的窗口,它是一個(gè)裝在發(fā)送端的可滑動(dòng)窗口,窗口的大小是不超過(guò)接收端確認(rèn)通知的窗口。
擁塞窗口指在接收方確認(rèn)數(shù)據(jù)包之前,發(fā)送方可以發(fā)送的TCP包的數(shù)據(jù)。(如擁塞窗口指定為1的情況,那么發(fā)送方就發(fā)出1個(gè)數(shù)據(jù)包之后,只有接收方確認(rèn)了那個(gè)發(fā)出的數(shù)據(jù)包,才能發(fā)送下一個(gè))
擁塞控制能防止過(guò)多的數(shù)據(jù)注入到網(wǎng)絡(luò)中,用于避免網(wǎng)絡(luò)過(guò)載,TCP中可以通過(guò)慢啟動(dòng)探索當(dāng)前連接對(duì)應(yīng)擁塞窗口的合適大小。即發(fā)送者發(fā)送數(shù)據(jù)的時(shí)候并非一開(kāi)始注入大量數(shù)據(jù)到網(wǎng)絡(luò)中,而是發(fā)送一個(gè)數(shù)據(jù)包進(jìn)行測(cè)試,當(dāng)?shù)玫酱_認(rèn)回復(fù)后,額外發(fā)送一個(gè)未確認(rèn)包。
這意味著得到一個(gè)確認(rèn)回復(fù),可以發(fā)送兩個(gè)數(shù)據(jù)包,得到兩個(gè)確認(rèn)回復(fù),可以發(fā)送四個(gè)數(shù)據(jù)包,以幾何形式增長(zhǎng)很快到達(dá)協(xié)議規(guī)定的擁塞窗口大小(發(fā)包數(shù)上限),這時(shí)候連接進(jìn)入擁塞避免階段,這種機(jī)制需要往返幾次才能得知最佳擁塞窗口大小,但往返幾次所需的時(shí)間成本不可忽略。
tcp中的慢啟動(dòng)概念,是用來(lái)探索當(dāng)前連接對(duì)應(yīng)擁塞窗口的合適大小。用來(lái)弄清楚新連接當(dāng)前的網(wǎng)絡(luò)情況。“慢速啟動(dòng)”是在連接建立后,每收到一個(gè)來(lái)自收端的確認(rèn),就控制窗口增加一個(gè)段值大小,當(dāng)窗口值達(dá)到“慢速啟動(dòng)”的限值后,慢速啟動(dòng)便停止工作,避免了網(wǎng)絡(luò)發(fā)生擁塞。
TCP傳輸控制協(xié)議的設(shè)計(jì)思路是,對(duì)假設(shè)情況很保守情況下,能夠公平對(duì)待同一網(wǎng)絡(luò)的不同流量的應(yīng)用,它的避免擁塞機(jī)制被設(shè)計(jì)城即使在最差的網(wǎng)絡(luò)情況下也可以起作用。
臃腫的消息首部,HTTP/1.1能壓縮請(qǐng)求內(nèi)容,但是消息首部卻不能壓縮。它可能占據(jù)請(qǐng)求的絕大部分(也可能是全部)也是比較常見(jiàn)了。(在這里如果能壓縮請(qǐng)求首部,把請(qǐng)求變得更小,就能夠緩解帶寬壓力了,降低系統(tǒng)的總負(fù)載)
受限的優(yōu)先級(jí)設(shè)置,即如果瀏覽器針對(duì)指定域名開(kāi)啟多個(gè)socket請(qǐng)求,若web頁(yè)面某些資源會(huì)比另外一些資源重要,會(huì)加重資源的排隊(duì)效應(yīng),會(huì)延遲請(qǐng)求其他的資源,優(yōu)先級(jí)高的資源先獲取,優(yōu)先級(jí)低的資源會(huì)在資源高的資源處理完成,(在處理過(guò)程中,瀏覽器不會(huì)發(fā)起新的資源請(qǐng)求)等待高的完成后再發(fā)起請(qǐng)求,(這就會(huì)讓總的頁(yè)面下載時(shí)間延長(zhǎng))。
在請(qǐng)求優(yōu)先級(jí)高的資源的時(shí)間區(qū)間內(nèi)瀏覽器并不會(huì)發(fā)起優(yōu)先級(jí)較低的新請(qǐng)求
小結(jié):HTTP1.1慢啟動(dòng)影響資源首次加載速度,TCP建立連接后,會(huì)開(kāi)始請(qǐng)求傳輸,開(kāi)始比較慢,然后不斷加快,為了防止出現(xiàn)網(wǎng)絡(luò)擁堵,會(huì)讓頁(yè)面的首次渲染時(shí)間變長(zhǎng)。開(kāi)始多個(gè)tcp,如出現(xiàn)網(wǎng)絡(luò)下降,無(wú)法識(shí)別資源的優(yōu)先級(jí),會(huì)出現(xiàn)靜態(tài)問(wèn)題。
數(shù)據(jù)壓縮,在瀏覽器中發(fā)送請(qǐng)求時(shí)會(huì)帶著Content-Encoding: gzip,里面時(shí)瀏覽器支持的壓縮格式列表,有多種如,gzip,deflate,br等。這樣服務(wù)器就可以從中選擇一個(gè)壓縮算法,放進(jìn)Content-Encoding響應(yīng)頭里,再把原數(shù)據(jù)壓縮后發(fā)給瀏覽器。
分塊傳輸,就是將傳輸?shù)奈募纸獬啥鄠€(gè)小塊,然后分發(fā)給瀏覽器,瀏覽器收到后再重新組裝復(fù)原。
每個(gè)分開(kāi)包含兩個(gè)部分,分塊長(zhǎng)度和分塊數(shù)據(jù)(長(zhǎng)度頭和數(shù)據(jù)塊),長(zhǎng)度頭以CRLF結(jié)尾的一行明文,數(shù)據(jù)塊緊跟在長(zhǎng)度頭后面,也是用CRLF結(jié)尾,最后用一個(gè)長(zhǎng)度為0的塊表示結(jié)束。
在響應(yīng)報(bào)文里用頭字段Transfer-Encoding:chunked表示報(bào)文里的body部分不是一次性發(fā)送過(guò)來(lái)的,而是分成了許多塊逐個(gè)發(fā)送的。
在Transfer-Encoding:chunked和Content-Length中,這兩個(gè)字段是互斥的。
一個(gè)響應(yīng)報(bào)文的傳輸長(zhǎng)度要么已知,要么長(zhǎng)度未知(chunked)。
Content-Length: 299
斷點(diǎn)續(xù)傳
要實(shí)現(xiàn)該功能需要制定下載的實(shí)體范圍,這種制定范圍發(fā)送請(qǐng)求叫做范圍請(qǐng)求。
Accept-Ranges:服務(wù)器使用http響應(yīng)頭Accept-Ranges標(biāo)識(shí)自身支持范圍請(qǐng)求,字段的具體值用于定義范圍請(qǐng)求的單位。
語(yǔ)法
Accept-Ranges: bytes,范圍請(qǐng)求的單位是 bytes (字節(jié))
Accept-Ranges: none,不支持任何范圍請(qǐng)求單位
范圍請(qǐng)求時(shí)用于不需要全部數(shù)據(jù),只需要其中的部分請(qǐng)求時(shí),可以使用范圍請(qǐng)求,允許客戶端在請(qǐng)求頭里使用專用字段來(lái)表示只獲取文件的一部分。
Range的格式,請(qǐng)求頭Range是HTTP范圍請(qǐng)求的專用字段,格式是“bytes=x-y”,以字節(jié)為單位的數(shù)據(jù)范圍。
示例:
執(zhí)行范圍時(shí)會(huì)使用頭部字段 Range 來(lái)指定資源 byte 的范圍。
Range格式:
5001-10000字節(jié)
Range : byte=5001-10000
5000之后的
Range : byte=5001-
0-3000字節(jié),5001-10000字節(jié)
Range : byte=-3000,5001-10000
上圖表示服務(wù)器收到Range字段后,檢測(cè)范圍合法性,范圍越界,就會(huì)返回狀態(tài)碼416,如你的文件只有1000個(gè)字節(jié),但請(qǐng)求范圍在20000-3000,就會(huì)導(dǎo)致這個(gè)狀態(tài)碼的出現(xiàn)。
如果成功讀取文件,范圍正確,返回狀態(tài)碼“206”。服務(wù)器要添加一個(gè)響應(yīng)頭字段Content-Range,告訴片段的實(shí)際偏移量和資源的總大小。
最后是發(fā)送數(shù)據(jù),直接把片段用TCP發(fā)給客戶端,一個(gè)范圍請(qǐng)求就算是處理完了。
格式是“bytes x-y/length”,與Range頭區(qū)別在沒(méi)有“=”
Content-Range: bytes 0-4395719/4395720
多端數(shù)據(jù),就是在Range頭里使用多個(gè)“x-y",一次性獲取多個(gè)片段數(shù)據(jù)。使用一種特殊的MIME類型:“multipart/byteranges”,用來(lái)表示響應(yīng)報(bào)文包含了多個(gè)范圍時(shí)使用。多種范圍請(qǐng)求 響應(yīng)會(huì)在頭部 Content-Type 表明 multipart-byteranges。
多段數(shù)據(jù)圖:分隔標(biāo)記boundary來(lái)區(qū)分不同的分段
存儲(chǔ)的大小
cookie的數(shù)據(jù)大小不能超過(guò)4k;sessionStorage和localStorage雖然也有存儲(chǔ)大小的限制,但比cookie大得多,可以達(dá)到5M或者更大。
有限期時(shí)間
因?yàn)镃DN緩存更方便;突破瀏覽器并發(fā)限制;節(jié)約cookie帶寬;節(jié)約主域名得連接數(shù),優(yōu)化頁(yè)面響應(yīng)速度;防止不必要得安全性問(wèn)題。
http2是超文本傳輸協(xié)議的第二版,相比http1協(xié)議的文本傳輸格式,http2是以二進(jìn)制的格式進(jìn)行數(shù)據(jù)傳輸?shù)模哂懈〉膫鬏旙w積以及負(fù)載。
http2.0分層,分幀層(http2多路復(fù)用能力的核心部分),數(shù)據(jù)或http層(包含傳統(tǒng)上被認(rèn)為是 HTTP 及其關(guān)聯(lián)數(shù)據(jù)的部分)。
HTTP2.0:
HTTP/2較HTTP/1.1優(yōu)化亮點(diǎn)
多路復(fù)用的實(shí)現(xiàn):
在單個(gè)域名下仍可以建立一個(gè)TCP管道,使用一個(gè)TCP長(zhǎng)連接,下載整個(gè)資源頁(yè)面,只需要一次慢啟動(dòng),并且避免了靜態(tài),瀏覽器發(fā)起請(qǐng)求,分幀層會(huì)對(duì)每個(gè)請(qǐng)求進(jìn)行分割,將同一個(gè)請(qǐng)求的分割塊打上相同的id編號(hào),然后通過(guò)協(xié)議棧將所有的分割體發(fā)送給服務(wù)器,然后通過(guò)服務(wù)器的分幀層根據(jù)id編號(hào)進(jìn)行請(qǐng)求組裝,服務(wù)器的分幀層將回應(yīng)數(shù)據(jù)分割按同一個(gè)回應(yīng)體進(jìn)行ID分割回應(yīng)給客戶端,客戶端拼裝回應(yīng)。
對(duì)于http2中的幀(frame),http1不是基于幀(frame)的,是文本分隔的。
GET/HTTP/1.1 <crlf>
這樣,對(duì)于http1的請(qǐng)求或者是響應(yīng)可能有的問(wèn)題:
HTTP/1 的請(qǐng)求和響應(yīng)報(bào)文,是由起始行、首部和正文組成,換行符分隔;HTTP/2是將請(qǐng)求和響應(yīng)數(shù)據(jù)分割成更小的幀,采用二進(jìn)制編碼,易于解析的。
參考圖片:
幀結(jié)構(gòu)總結(jié) 所有的幀都包含一個(gè)9 byte的幀頭 + 可邊長(zhǎng)的正文不同。根據(jù)幀的類型不同,正文部分的結(jié)構(gòu)也不一樣。
幀頭:
http2作為一個(gè)二進(jìn)制協(xié)議,擁有包含輕量型,安全和快速在內(nèi)的所有優(yōu)勢(shì),保留了原始的http協(xié)議語(yǔ)義,對(duì)于http2更改了在系統(tǒng)之間傳輸數(shù)據(jù)的方式。
二進(jìn)制分幀層(binary framing layer),所有通信都在單個(gè)TCP連接上執(zhí)行,該連接在整個(gè)對(duì)話期間一直處于打開(kāi)狀態(tài),主要是二進(jìn)制協(xié)議將通信分解為幀的方式,這些幀交織在客戶端與服務(wù)器之間的雙向邏輯流中。
HTTP/2 連接的拓?fù)浣Y(jié)構(gòu)(展示了一個(gè)用于建立多個(gè)流的連接)
在流 1 中,發(fā)送了一條請(qǐng)求消息,并返回了相應(yīng)的響應(yīng)消息。
HTTP/2 幀結(jié)構(gòu)
前9個(gè)字節(jié)對(duì)于每個(gè)幀是一致的。解析時(shí)只需要讀取這些字節(jié),就可以準(zhǔn)確地知道在整個(gè)幀中期望的字節(jié)數(shù)。
幀首部字段表格:
名稱長(zhǎng)度描述length3字節(jié)表示幀負(fù)載的長(zhǎng)度type1字節(jié)當(dāng)前幀類型Flags1字節(jié)具體幀類型的標(biāo)識(shí)R1位保留位,不要設(shè)置,否則會(huì)帶來(lái)嚴(yán)重后果Stream Identifier31位每個(gè)流的唯一IDFrame Payload長(zhǎng)度可變真實(shí)的幀內(nèi)容,長(zhǎng)度是在length字段中設(shè)置的
備注:流Id是用來(lái)標(biāo)識(shí)幀所屬的流。流看作在連接上的一系列幀,它們構(gòu)成了單獨(dú)的 HTTP 請(qǐng)求和響應(yīng)。
對(duì)于http1 的請(qǐng)求和響應(yīng)都分成消息首部和消息體兩部分;http2 從上面一張圖可以知道,http2的請(qǐng)求和響應(yīng)分成HEADERS 幀和 DATA 幀。
比較一下:
http2的一個(gè)重要特性是基于流的流量控制。提供了客戶端調(diào)整傳輸速度的能力。其中WINDOW_UPDATE 幀用來(lái)指示流量控制信息。
有了多路復(fù)用,客戶端可以一次發(fā)出多有資源的請(qǐng)求,不用像http1那樣,發(fā)出對(duì)新對(duì)象請(qǐng)求之前,需要等待前一個(gè)響應(yīng)完成。所以瀏覽器失去了在Http1中的默認(rèn)資源請(qǐng)求優(yōu)先級(jí)策略。
http的頭字段
頭字段類型含義Date表示請(qǐng)求和響應(yīng)生成的日期Pragma表示數(shù)據(jù)是否允許緩存的通信選項(xiàng)Cache-Control控制緩存的相關(guān)信息Connection設(shè)置發(fā)送響應(yīng)之后TCP連接是否繼續(xù)保持的通信選項(xiàng)Transfer-Encoding表示消息主體的編碼格式Via記錄途中經(jīng)過(guò)的代理和網(wǎng)關(guān)Authorization身份認(rèn)證數(shù)據(jù)From請(qǐng)求發(fā)送者的郵件地址Referer當(dāng)通過(guò)點(diǎn)擊超級(jí)鏈接進(jìn)入下一個(gè)頁(yè)面時(shí),在這里會(huì)記錄下上一個(gè)頁(yè)面的URIUser-Agent客戶端軟件的名稱和版本號(hào)等相關(guān)信息Accept客戶端可支持的數(shù)據(jù)類型,以MIME類型來(lái)表示Accept-Charset客戶端可支持的字符集Accept-Language客戶端可支持的語(yǔ)言Host接收請(qǐng)求的服務(wù)器ip地址和端口號(hào)Range當(dāng)需要只獲取部分?jǐn)?shù)據(jù)而不是全部數(shù)據(jù)時(shí),可通過(guò)這個(gè)字段指定要獲取的數(shù)據(jù)范圍Location表示信息的準(zhǔn)確位置Server服務(wù)器程序的名稱和版本號(hào)等相關(guān)信息Allow表示指定的URI支持Content-Encoding當(dāng)消息體經(jīng)過(guò)壓縮等編碼處理時(shí),表示其編碼格式Content-Length表示消息體的長(zhǎng)度Content-Type表示消息體的數(shù)據(jù)類型,以MIME規(guī)格定義的數(shù)據(jù)類型來(lái)表示Expires表示消息體的有效期Last-Modified數(shù)據(jù)的最后更新日期Content-Language表示消息體的語(yǔ)言Content-Location表示消息體在服務(wù)器上的位置Content-Range當(dāng)僅請(qǐng)求部分?jǐn)?shù)據(jù)時(shí),表示消息體包含的數(shù)據(jù)范圍
HTTP消息示例:
IP 的基本思路
Ip地址的表示方法
IP地址的結(jié)構(gòu)-子網(wǎng)掩碼表示網(wǎng)絡(luò)號(hào)與主機(jī)號(hào)之間的邊界。
解析器的調(diào)用方法
DNS服務(wù)器的基本工作
DNS 服務(wù)器之間的查詢操作
數(shù)據(jù)通過(guò)類似管道的結(jié)構(gòu)來(lái)流動(dòng)
們經(jīng)常使用第三方的對(duì)象存儲(chǔ)服務(wù),比如七牛云或阿里云,他們都提供了“智能媒體服務(wù)”,其實(shí)就是在鏈接上加上各種參數(shù),實(shí)現(xiàn)圖片的裁剪、縮放等,可以便捷的實(shí)現(xiàn)縮略圖,節(jié)省網(wǎng)絡(luò)寬帶,加快頁(yè)面的訪問(wèn)。
原理很簡(jiǎn)單,就是接收參數(shù)然后處理唄。如果用PHP做的話,不難,但是卻要寫(xiě)好多代碼。操作GD庫(kù)太麻煩了。但現(xiàn)在,只要兩行代碼就能實(shí)現(xiàn)一套強(qiáng)大的圖片處理功能。
// 實(shí)例化
$server=League\Glide\ServerFactory::create([
'source'=> 'path/to/source/folder',
'cache'=> 'path/to/cache/folder',
]);
// 可以在第二個(gè)參數(shù)傳入數(shù)組
$server->outputImage('users/1.jpg', ['w'=> 300, 'h'=> 400]);
// 更簡(jiǎn)單的做法,直接傳入GET參數(shù)
$server->outputImage($path, $_GET);
glide可以接收26個(gè)參數(shù),幾乎可以涵蓋所有的場(chǎng)景需求。
名稱 | 功能參數(shù) | 介紹 |
方向 | or | 旋轉(zhuǎn)圖像,支持0, 90, 180或者 270,同時(shí)支持auto,會(huì)根據(jù)圖片的Exif 信息自動(dòng)確定位置 |
翻轉(zhuǎn) | flip | 翻轉(zhuǎn)圖像,支持水平、垂直、圓心等 |
裁剪 | crop | 將圖像裁剪到指定尺寸,支持居中、左上角、居左等10多個(gè)設(shè)置 |
寬度 | w | 設(shè)置圖像的寬度,根據(jù)fit參數(shù)表現(xiàn)不同 |
高度 | h | 設(shè)置圖像的高度,根據(jù)fit參數(shù)表現(xiàn)不同 |
尺寸效果 | fit | 設(shè)置圖像如何適應(yīng)新的尺寸,顯示最大寬度、最小寬度、變形、裁剪等等6中效果 |
設(shè)備像素比 | dpr | 通過(guò)此參數(shù)可以生成不同像素比的圖片,在蘋(píng)果和安卓設(shè)備中有更好的表現(xiàn),最大8 |
亮度 | bri | 調(diào)整圖像亮度 |
對(duì)比度 | con | 調(diào)整圖像對(duì)比度 |
伽馬 | gam | 調(diào)整圖像伽馬值值 |
銳化 | sharp | 銳化圖像 |
模糊 | blur | 為圖像增加模糊效果 |
像素化 | pixel | 為圖像增加像素化效果 |
濾鏡 | filt | 能夠指定使用那些濾鏡處理圖像,內(nèi)置灰度和褐色,可以自定義。 |
水印路徑 | mark | 給圖像增加水印 |
水印寬度 | markw | 設(shè)置水印的寬度 |
水印高度 | markh | 設(shè)置水印的高度 |
水印偏移量X | markx | 水印的X偏移量 |
水印偏移量Y | marky | 水印的Y偏移量 |
水印的填充 | markpad | 水印的填充,padding |
水印的定位 | markpos | 水印的位置,居左、居中等 |
水印的透明度 | markalpha | 設(shè)置水印的透明度 |
背景 | bg | 設(shè)置圖片的背景色 |
邊框 | border | 給圖片增加邊框 |
質(zhì)量 | q | 設(shè)置輸入的質(zhì)量 |
格式 | fm | 設(shè)置圖像的編碼格式,jpg、png等 |
本文對(duì)幾個(gè)重點(diǎn)的功能做個(gè)介紹。
設(shè)置圖像如何適應(yīng)新的尺寸。
支持的參數(shù):
當(dāng)尺寸效果設(shè)置為裁剪時(shí),可以使用裁剪參數(shù)。
裁剪位置:
您還可以通過(guò)添加裁剪位置來(lái)設(shè)置裁剪圖像的位置。 接受 crop-top-left, crop-top, crop-top-right, crop-left, crop-center, crop-right, crop-bottom-left, crop-bottom或者 crop-bottom-right. 默認(rèn)是 crop-center, 并且與 crop.
除了裁剪位置之外,您還可以使用焦點(diǎn)更具體地確定確切的裁剪位置。 這是使用兩個(gè)偏移百分比定義的: crop-x%-y%.
<img src="kayaks.jpg?w=300&h=300&fit=crop-25-75">
您還可以選擇通過(guò)提供第三個(gè)值來(lái)放大您的焦點(diǎn):一個(gè)介于 1 和 100 之間的浮點(diǎn)數(shù)。每個(gè)完整步長(zhǎng)相當(dāng)于 100% 縮放。 (例如。 x%-y%-2相當(dāng)于以 200% 的比例查看圖像)。 建議的范圍是 1-10。
<img src="kayaks.jpg?w=300&h=300&fit=crop-25-75-2">
預(yù)裁剪
在任何其他調(diào)整大小操作之前將圖像裁剪為特定尺寸。 要求的格式: width,height,x,y. 就像使用截圖工具那樣,在先在圖片上截取一段。
<img src="kayaks.jpg?crop=100,100,915,155">
可以使用flysystem驅(qū)動(dòng),這意味著不僅可以操作本地的文件,還支持各類存儲(chǔ)方式,比如SFTP、FTP、對(duì)象存儲(chǔ)等等。
// 圖片地址
$source=new League\Flysystem\Filesystem(
new League\Flysystem\Local\LocalFilesystemAdapter('path/to/source/folder')
);
// 緩存地址
$cache=new League\Flysystem\Filesystem(
new League\Flysystem\Local\LocalFilesystemAdapter('path/to/cache/folder')
);
$server=new League\Glide\Server(
$source,
$cache,
);
可以通過(guò)getImageResponse方法獲取標(biāo)準(zhǔn)的PSR-7響應(yīng)對(duì)象,同時(shí)官方提供了laravel等框架的擴(kuò)展響應(yīng)對(duì)象。
可以設(shè)置默認(rèn)的圖片處理設(shè)置。
$server=League\Glide\ServerFactory::create([
'defaults'=> [
'mark'=> 'logo.png',
'markw'=> '30w',
'markpad'=> '5w',
]
]);
可以提前將各種參數(shù)設(shè)置好,然后直接傳入預(yù)設(shè)的名稱即可。比如下面的代碼:
<?php
$server=League\Glide\ServerFactory::create([
'presets'=> [
'small'=> [
'w'=> 200,
'h'=> 200,
'fit'=> 'crop',
],
'medium'=> [
'w'=> 600,
'h'=> 400,
'fit'=> 'crop',
]
]
]);
然后直接使用預(yù)設(shè)就可以了:
<img src="kayaks.jpg?p=small">
也可以同時(shí)使用多個(gè)預(yù)設(shè):
<img src="kayaks.jpg?p=small,watermarked">
甚至可以使用帶有附加參數(shù)的預(yù)設(shè):
<img src="kayaks.jpg?p=small,watermarked&filt=sepia">
支持GD庫(kù)和Imagick庫(kù)。
$server=League\Glide\ServerFactory::create([
// 默認(rèn)使用GD
'driver'=> 'gd',
// 使用ImageMagick
'driver'=> 'imagick',
]);
使用compsoer安裝即可。
composer require league/glide
glide提供了一套簽名機(jī)制,通過(guò)私鑰(一長(zhǎng)串字符)生成一個(gè)token,只有攜帶了這個(gè)token 才能調(diào)用參數(shù),避免人們通過(guò)大量的圖像調(diào)整參數(shù)攻擊服務(wù)器。
<?php
use League\Glide\Signatures\SignatureFactory;
use League\Glide\Signatures\SignatureException;
try {
// 設(shè)置秘鑰
$signkey='v-LK4WCdhcfcc%jt*VC2cj%nVpu+xQKvLUA%H86kRVk_4bgG8&CWM#k*b_7MUJpmTc=4GFmKFp7=K%67je-skxC5vz+r#xT?62tT?Aw%FtQ4Y3gvnwHTwqhxUh89wCa_';
// 驗(yàn)證訪問(wèn)
SignatureFactory::create($signkey)->validateRequest($path, $_GET);
} catch (SignatureException $e) {
// 處理異常
}
<?php
use League\Glide\Urls\UrlBuilderFactory;
// 上面的那個(gè)秘鑰
$signkey='v-LK4WCdhcfcc%jt*VC2cj%nVpu+xQKvLUA%H86kRVk_4bgG8&CWM#k*b_7MUJpmTc=4GFmKFp7=K%67je-skxC5vz+r#xT?62tT?Aw%FtQ4Y3gvnwHTwqhxUh89wCa_';
// 實(shí)例化
$urlBuilder=UrlBuilderFactory::create('/img/', $signkey);
// 生成url
$url=$urlBuilder->getUrl('cat.jpg', ['w'=> 500]);
// 使用url
echo '<img src="'.$url.'">';
// 輸入預(yù)覽
<img src="/img/cat.jpg?w=500&s=af3dc18fc6bfb2afb521e587c348b904">
只要簡(jiǎn)單的幾行代碼,就實(shí)現(xiàn)了一套健全的圖片處理HTTP服務(wù),當(dāng)你有類似的需求的時(shí)候,抓緊用上吧。
原文標(biāo)題:[league/glide]兩行代碼實(shí)現(xiàn)一套強(qiáng)大的圖片處理HTTP服務(wù)
原文地址:https://phpreturn.com/index/a64084605c3759.html
原文平臺(tái):PHP武器庫(kù)
版權(quán)聲明:本文由phpreturn.com(PHP武器庫(kù)官網(wǎng))原創(chuàng)和首發(fā),所有權(quán)利歸phpreturn(PHP武器庫(kù))所有,本站允許任何形式的轉(zhuǎn)載/引用文章,但必須同時(shí)注明出處。
者有話要說(shuō):此文是作者自己的學(xué)習(xí)總結(jié),供大家參考,不足之處還請(qǐng)見(jiàn)諒和指正~
在學(xué)習(xí)完了基本的HTML+CSS標(biāo)簽之后,就可以嘗試寫(xiě)一些簡(jiǎn)單的靜態(tài)網(wǎng)頁(yè)啦~練習(xí)的過(guò)程是充滿成就感的,值得反復(fù)體會(huì)和思考!
網(wǎng)頁(yè)結(jié)構(gòu)
簡(jiǎn)單提一下常用于表示網(wǎng)頁(yè)機(jī)構(gòu)的標(biāo)簽:
header 整個(gè)頁(yè)面的標(biāo)題(也可表示一個(gè)內(nèi)容區(qū)塊)
main 頁(yè)面主體部分
footer 整個(gè)頁(yè)面的腳注(也可表示一個(gè)內(nèi)容區(qū)塊)
article 一塊與上下文無(wú)關(guān)的獨(dú)立內(nèi)容
section 表示一個(gè)內(nèi)容區(qū)塊,常嵌套于article中
aside 在article之外與其內(nèi)容相關(guān)的輔助信息
nav 頁(yè)面中的導(dǎo)航欄
figure 表示一段獨(dú)立的流內(nèi)容
基本網(wǎng)站結(jié)構(gòu)
三欄布局
一個(gè)網(wǎng)頁(yè)最少由header、main、footer三部分組成,那么從三欄布局開(kāi)始練習(xí)吧。無(wú)論是上-中-下結(jié)構(gòu)還是左-中-右結(jié)構(gòu),關(guān)鍵都在于設(shè)置中間部分的寬高或位置。我們知道網(wǎng)頁(yè)的主體內(nèi)容(版心)是處于居中位置、隨網(wǎng)頁(yè)縮放而縮放的。那么左右(或上下)兩欄固定后,須使中間部分自適應(yīng)。以下總結(jié)了幾種三欄布局的方法,以左-中-右結(jié)構(gòu)為例:
先寫(xiě)左中右三個(gè)盒子。
body部分
1.使用float
利用float使左右脫離文檔流
需要注意的是,使用float方法需要在body部分改一下center盒子的位置,把center盒子放在right盒子之后(否則right盒子會(huì)跑到下一行右側(cè))。以上代碼中,設(shè)置center盒子的左右外邊距來(lái)實(shí)現(xiàn)寬度自適應(yīng),若父盒子layout無(wú)高度要求,可用min-height實(shí)現(xiàn)高度自適應(yīng)。不加高度自適應(yīng)也可,在未設(shè)置center盒子高度的情況下本身高度會(huì)隨文本內(nèi)容的擴(kuò)充而自動(dòng)增加。
2.使用position
利用絕對(duì)定位脫離文檔流
三個(gè)盒子都分別使用絕對(duì)定位,left、right分別距離窗口左右端為0,center距離窗口左端的間距為left盒子的寬度,距離窗口右端的間距為right盒子的寬度。
3.使用flex
利用彈性盒固有屬性
須給父盒子layout加上彈性盒屬性,給center盒子設(shè)置大于0的flex值,利用彈性盒自動(dòng)拉伸效果實(shí)現(xiàn)center盒子的寬度自適應(yīng)。
4.使用table
設(shè)置為表格
給父盒子layout設(shè)置為table,寬度為整個(gè)窗口,給三個(gè)子盒子都設(shè)置為table-cell,此時(shí)三個(gè)盒子就有了表格的屬性。固定left、right盒子的寬度,center盒子自動(dòng)占滿父盒子剩余寬度。需要注意的是,因?yàn)楦负凶泳哂斜砀駥傩裕?dāng)left、center、right三者中任意一個(gè)盒子高度改變時(shí),其他兩個(gè)盒子會(huì)跟著改變。
5.使用grid
設(shè)置為網(wǎng)格
將父盒子layout設(shè)置為grid,寬度為整個(gè)窗口,用template-rows設(shè)置行高,用template-columns分別設(shè)置三個(gè)盒子的寬度,其中auto實(shí)現(xiàn)center盒子的寬度自適應(yīng)。需要注意的是,這里用template-rows設(shè)置了固定的行高,因此center的高度不會(huì)自適應(yīng)。
仿寫(xiě)練習(xí)
適合初學(xué)者練習(xí)的網(wǎng)頁(yè)有很多,可以打開(kāi)網(wǎng)址之家去里面挑一挑,以靜態(tài)頁(yè)面為主的網(wǎng)站。作者自己是以豆瓣首頁(yè)(局部)進(jìn)行練習(xí)的。練習(xí)過(guò)程中,千萬(wàn)不要去看網(wǎng)站源碼(此時(shí)你也有很多地方看不懂),先試著自己分析和思考,用所學(xué)的知識(shí)看看能做到哪一步。
筆者學(xué)習(xí)時(shí)的仿寫(xiě)
放上對(duì)比圖,還是有很多不一樣的地方,網(wǎng)頁(yè)也沒(méi)有功能,作為初學(xué)者這都是正常的。靜態(tài)網(wǎng)頁(yè)練習(xí)的主要目的是熟悉HTML+CSS布局,培養(yǎng)做網(wǎng)頁(yè)的思維。具體細(xì)節(jié)隨著學(xué)習(xí)的深入,可以讓網(wǎng)頁(yè)更還原、頁(yè)面更精美,網(wǎng)頁(yè)功能也能逐步完善起來(lái),實(shí)現(xiàn)真正的網(wǎng)站開(kāi)發(fā)。
*請(qǐng)認(rèn)真填寫(xiě)需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。