1、輸入地址
當(dāng)我們開始在瀏覽器中輸入網(wǎng)址的時候蹦疑,瀏覽器其實(shí)就已經(jīng)在智能的匹配可能得 url 了,他會從歷史記錄萨驶,書簽等地方歉摧,找到已經(jīng)輸入的字符串可能對應(yīng)的 url,然后給出智能提示腔呜,讓你可以補(bǔ)全url地址叁温。對于 google的chrome 的瀏覽器,他甚至?xí)苯訌木彺嬷邪丫W(wǎng)頁展示出來核畴,就是說膝但,你還沒有按下 enter,頁面就出來了谤草。
2跟束、瀏覽器查找域名的 IP 地址
1、請求一旦發(fā)起丑孩,瀏覽器首先要做的事情就是解析這個域名冀宴,一般來說,瀏覽器會首先查看本地硬盤的 hosts 文件温学,看看其中有沒有和這個域名對應(yīng)的規(guī)則略贮,如果有的話就直接使用 hosts 文件里面的 ip 地址。
2仗岖、如果在本地的 hosts 文件沒有能夠找到對應(yīng)的 ip 地址逃延,瀏覽器會發(fā)出一個 DNS請求到本地DNS服務(wù)器 。本地DNS服務(wù)器一般都是你的網(wǎng)絡(luò)接入服務(wù)器商提供箩帚,比如中國電信真友,中國移動黄痪。
3紧帕、查詢你輸入的網(wǎng)址的DNS請求到達(dá)本地DNS服務(wù)器之后,本地DNS服務(wù)器會首先查詢它的緩存記錄,如果緩存中有此條記錄是嗜,就可以直接返回結(jié)果愈案,此過程是遞歸的方式進(jìn)行查詢。如果沒有鹅搪,本地DNS服務(wù)器還要向DNS根服務(wù)器進(jìn)行查詢站绪。
4、根DNS服務(wù)器沒有記錄具體的域名和IP地址的對應(yīng)關(guān)系丽柿,而是告訴本地DNS服務(wù)器恢准,你可以到域服務(wù)器上去繼續(xù)查詢,并給出域服務(wù)器的地址甫题。這種過程是迭代的過程馁筐。
5、本地DNS服務(wù)器繼續(xù)向域服務(wù)器發(fā)出請求坠非,在這個例子中敏沉,請求的對象是.com域服務(wù)器。.com域服務(wù)器收到請求之后炎码,也不會直接返回域名和IP地址的對應(yīng)關(guān)系盟迟,而是告訴本地DNS服務(wù)器,你的域名的解析服務(wù)器的地址潦闲。
6攒菠、最后,本地DNS服務(wù)器向域名的解析服務(wù)器發(fā)出請求歉闰,這時就能收到一個域名和IP地址對應(yīng)關(guān)系要尔,本地DNS服務(wù)器不僅要把IP地址返回給用戶電腦,還要把這個對應(yīng)關(guān)系保存在緩存中新娜,以備下次別的用戶查詢時赵辕,可以直接返回結(jié)果,加快網(wǎng)絡(luò)訪問概龄。
下面這張圖很完美的解釋了這一過程:
知識擴(kuò)展:
1)什么是DNS还惠?
DNS(Domain Name System,域名系統(tǒng))私杜,因特網(wǎng)上作為域名和IP地址相互映射的一個分布式數(shù)據(jù)庫蚕键,能夠使用戶更方便的訪問互聯(lián)網(wǎng),而不用去記住能夠被機(jī)器直接讀取的IP數(shù)串衰粹。通過主機(jī)名锣光,最終得到該主機(jī)名對應(yīng)的IP地址的過程叫做域名解析(或主機(jī)名解析)。
通俗的講铝耻,我們更習(xí)慣于記住一個網(wǎng)站的名字誊爹,比如www.baidu.com,而不是記住它的ip地址蹬刷,比如:167.23.10.2。而計算機(jī)更擅長記住網(wǎng)站的ip地址频丘,而不是像www.baidu.com等鏈接办成。因?yàn)椋珼NS就相當(dāng)于一個電話本搂漠,比如你要找www.baidu.com這個域名迂卢,那我翻一翻我的電話本,我就知道桐汤,哦而克,它的電話(ip)是167.23.10.2。
2)DNS查詢的兩種方式:遞歸查詢和迭代查詢
1怔毛、遞歸解析
當(dāng)局部DNS服務(wù)器自己不能回答客戶機(jī)的DNS查詢時拍摇,它就需要向其他DNS服務(wù)器進(jìn)行查詢。此時有兩種方式馆截,如圖所示的是遞歸方式充活。局部DNS服務(wù)器自己負(fù)責(zé)向其他DNS服務(wù)器進(jìn)行查詢,一般是先向該域名的根域服務(wù)器查詢蜡娶,再由根域名服務(wù)器一級級向下查詢混卵。最后得到的查詢結(jié)果返回給局部DNS服務(wù)器,再由局部DNS服務(wù)器返回給客戶端窖张。
2幕随、迭代解析
當(dāng)局部DNS服務(wù)器自己不能回答客戶機(jī)的DNS查詢時,也可以通過迭代查詢的方式進(jìn)行解析宿接,如圖所示赘淮。局部DNS服務(wù)器不是自己向其他DNS服務(wù)器進(jìn)行查詢,而是把能解析該域名的其他DNS服務(wù)器的IP地址返回給客戶端DNS程序睦霎,客戶端DNS程序再繼續(xù)向這些DNS服務(wù)器進(jìn)行查詢梢卸,直到得到查詢結(jié)果為止。也就是說副女,迭代解析只是幫你找到相關(guān)的服務(wù)器而已蛤高,而不會幫你去查。比如說:baidu.com的服務(wù)器ip地址在192.168.4.5這里碑幅,你自己去查吧戴陡,本人比較忙,只能幫你到這里了沟涨。
3)DNS域名稱空間的組織方式
我們在前面有說到根DNS服務(wù)器恤批,域DNS服務(wù)器,這些都是DNS域名稱空間的組織方式裹赴。按其功能命名空間中用來描述 DNS 域名稱的五個類別的介紹詳見下表中喜庞,以及與每個名稱類型的示例
(盜圖)
4)DNS負(fù)載均衡
當(dāng)一個網(wǎng)站有足夠多的用戶的時候诀浪,假如每次請求的資源都位于同一臺機(jī)器上面,那么這臺機(jī)器隨時可能會蹦掉赋荆。處理辦法就是用DNS負(fù)載均衡技術(shù)笋妥,它的原理是在DNS服務(wù)器中為同一個主機(jī)名配置多個IP地址,在應(yīng)答DNS查詢時,DNS服務(wù)器對每個查詢將以DNS文件中主機(jī)記錄的IP地址按順序返回不同的解析結(jié)果,將客戶端的訪問引導(dǎo)到不同的機(jī)器上去,使得不同的客戶端訪問不同的服務(wù)器,從而達(dá)到負(fù)載均衡的目的?例如可以根據(jù)每臺機(jī)器的負(fù)載量懊昨,該機(jī)器離用戶地理位置的距離等等窄潭。
3、瀏覽器向 web 服務(wù)器發(fā)送一個 HTTP 請求
拿到域名對應(yīng)的IP地址之后酵颁,瀏覽器會以一個隨機(jī)端口(1024<端口<65535)向服務(wù)器的WEB程序(常用的有httpd,nginx等)80端口發(fā)起TCP的連接請求嫉你。這個連接請求到達(dá)服務(wù)器端后(這中間通過各種路由設(shè)備,局域網(wǎng)內(nèi)除外)躏惋,進(jìn)入到網(wǎng)卡幽污,然后是進(jìn)入到內(nèi)核的TCP/IP協(xié)議棧(用于識別該連接請求,解封包簿姨,一層一層的剝開)距误,還有可能要經(jīng)過Netfilter防火墻(屬于內(nèi)核的模塊)的過濾,最終到達(dá)WEB程序扁位,最終建立了TCP/IP的連接准潭。
TCP連接如圖所示:
建立了TCP連接之后,發(fā)起一個http請求域仇。一個典型的 http request header 一般需要包括請求的方法刑然,例如 GET 或者 POST 等,不常用的還有 PUT 和 DELETE 暇务、HEAD泼掠、OPTION以及 TRACE 方法,一般的瀏覽器只能發(fā)起 GET 或者 POST 請求垦细。
客戶端向服務(wù)器發(fā)起http請求的時候择镇,會有一些請求信息,請求信息包含三個部分:
| 請求方法URI協(xié)議/版本
| 請求頭(Request Header)
| 請求正文:
下面是一個完整的HTTP請求例子:
GET/sample.jspHTTP/1.1
Accept:image/gif.image/jpeg,/
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=jinqiao&password=1234
注意:最后一個請求頭之后是一個空行括改,發(fā)送回車符和換行符沐鼠,通知服務(wù)器以下不再有請求頭。
(1)請求的第一行是“方法URL議/版本”:GET/sample.jsp HTTP/1.1
(2)請求頭(Request Header):請求頭包含許多有關(guān)的客戶端環(huán)境和請求正文的有用信息叹谁。例如饲梭,請求頭可以聲明瀏覽器所用的語言,請求正文的長度等焰檩。
Accept:image/gif.image/jpeg./
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
Accept-Encoding:gzip,deflate.
3)請求正文
請求頭和請求正文之間是一個空行憔涉,這個行非常重要,它表示請求頭已經(jīng)結(jié)束析苫,接下來的是請求正文兜叨。請求正文中可以包含客戶提交的查詢字符串信息:
username=jinqiao&password=1234
知識擴(kuò)展:
1)TCP三次握手
第一次握手:客戶端A將標(biāo)志位SYN置為1,隨機(jī)產(chǎn)生一個值為seq=J(J的取值范圍為=1234567)的數(shù)據(jù)包到服務(wù)器穿扳,客戶端A進(jìn)入SYN_SENT狀態(tài),等待服務(wù)端B確認(rèn)国旷;
第二次握手:服務(wù)端B收到數(shù)據(jù)包后由標(biāo)志位SYN=1知道客戶端A請求建立連接矛物,服務(wù)端B將標(biāo)志位SYN和ACK都置為1蟋滴,ack=J+1钾挟,隨機(jī)產(chǎn)生一個值seq=K,并將該數(shù)據(jù)包發(fā)送給客戶端A以確認(rèn)連接請求茂契,服務(wù)端B進(jìn)入SYN_RCVD狀態(tài)屡久。
第三次握手:客戶端A收到確認(rèn)后忆首,檢查ack是否為J+1,ACK是否為1被环,如果正確則將標(biāo)志位ACK置為1糙及,ack=K+1,并將該數(shù)據(jù)包發(fā)送給服務(wù)端B筛欢,服務(wù)端B檢查ack是否為K+1浸锨,ACK是否為1,如果正確則連接建立成功版姑,客戶端A和服務(wù)端B進(jìn)入ESTABLISHED狀態(tài)柱搜,完成三次握手,隨后客戶端A與服務(wù)端B之間可以開始傳輸數(shù)據(jù)了漠酿。
如圖所示:
2)為什需要三次握手冯凹?
《計算機(jī)網(wǎng)絡(luò)》第四版中講“三次握手”的目的是“為了防止已失效的連接請求報文段突然又傳送到了服務(wù)端,因而產(chǎn)生錯誤”
書中的例子是這樣的炒嘲,“已失效的連接請求報文段”的產(chǎn)生在這樣一種情況下:client發(fā)出的第一個連接請求報文段并沒有丟失宇姚,而是在某個網(wǎng)絡(luò)結(jié)點(diǎn)長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達(dá)server夫凸。本來這是一個早已失效的報文段浑劳。但server收到此失效的連接請求報文段后,就誤認(rèn)為是client再次發(fā)出的一個新的連接請求夭拌。于是就向client發(fā)出確認(rèn)報文段魔熏,同意建立連接。
假設(shè)不采用“三次握手”鸽扁,那么只要server發(fā)出確認(rèn)蒜绽,新的連接就建立了。由于現(xiàn)在client并沒有發(fā)出建立連接的請求桶现,因此不會理睬server的確認(rèn)躲雅,也不會向server發(fā)送數(shù)據(jù)。但server卻以為新的運(yùn)輸連接已經(jīng)建立骡和,并一直等待client發(fā)來數(shù)據(jù)相赁。這樣相寇,server的很多資源就白白浪費(fèi)掉了。采用“三次握手”的辦法可以防止上述現(xiàn)象發(fā)生钮科。例如剛才那種情況唤衫,client不會向server的確認(rèn)發(fā)出確認(rèn)。server由于收不到確認(rèn)绵脯,就知道client并沒有要求建立連接佳励。”桨嫁。主要目的防止server端一直等待植兰,浪費(fèi)資源份帐。
3)TCP四次揮手
第一次揮手:Client發(fā)送一個FIN璃吧,用來關(guān)閉Client到Server的數(shù)據(jù)傳送,Client進(jìn)入FIN_WAIT_1狀態(tài)废境。
第二次揮手:Server收到FIN后畜挨,發(fā)送一個ACK給Client,確認(rèn)序號為收到序號+1(與SYN相同噩凹,一個FIN占用一個序號)巴元,Server進(jìn)入CLOSE_WAIT狀態(tài)。
第三次揮手:Server發(fā)送一個FIN驮宴,用來關(guān)閉Server到Client的數(shù)據(jù)傳送逮刨,Server進(jìn)入LAST_ACK狀態(tài)。
第四次揮手:Client收到FIN后堵泽,Client進(jìn)入TIME_WAIT狀態(tài)修己,接著發(fā)送一個ACK給Server,確認(rèn)序號為收到序號+1迎罗,Server進(jìn)入CLOSED狀態(tài)睬愤,完成四次揮手。
4)為什么建立連接是三次握手纹安,而關(guān)閉連接卻是四次揮手呢尤辱?
這是因?yàn)榉?wù)端在LISTEN狀態(tài)下,收到建立連接請求的SYN報文后厢岂,把ACK和SYN放在一個報文里發(fā)送給客戶端光督。而關(guān)閉連接時,當(dāng)收到對方的FIN報文時塔粒,僅僅表示對方不再發(fā)送數(shù)據(jù)了但是還能接收數(shù)據(jù)结借,己方也未必全部數(shù)據(jù)都發(fā)送給對方了,所以己方可以立即close窗怒,也可以發(fā)送一些數(shù)據(jù)給對方后映跟,再發(fā)送FIN報文給對方來表示同意現(xiàn)在關(guān)閉連接蓄拣,因此,己方ACK和FIN一般都會分開發(fā)送努隙。
4球恤、服務(wù)器的永久重定向響應(yīng)
服務(wù)器給瀏覽器響應(yīng)一個301永久重定向響應(yīng),這樣瀏覽器就會訪問“http://www.google.com/” 而非“http://google.com/”荸镊。
為什么服務(wù)器一定要重定向而不是直接發(fā)送用戶想看的網(wǎng)頁內(nèi)容呢咽斧?其中一個原因跟搜索引擎排名有關(guān)。如果一個頁面有兩個地址躬存,就像http://www.yy.com/和http://yy.com/张惹,搜索引擎會認(rèn)為它們是兩個網(wǎng)站,結(jié)果造成每個搜索鏈接都減少從而降低排名岭洲。而搜索引擎知道301永久重定向是什么意思宛逗,這樣就會把訪問帶www的和不帶www的地址歸到同一個網(wǎng)站排名下。還有就是用不同的地址會造成緩存友好性變差盾剩,當(dāng)一個頁面有好幾個名字時雷激,它可能會在緩存里出現(xiàn)好幾次。
擴(kuò)展知識
1)301和302的區(qū)別告私。
301和302狀態(tài)碼都表示重定向屎暇,就是說瀏覽器在拿到服務(wù)器返回的這個狀態(tài)碼后會自動跳轉(zhuǎn)到一個新的URL地址,這個地址可以從響應(yīng)的Location首部中獲茸に凇(用戶看到的效果就是他輸入的地址A瞬間變成了另一個地址B)——這是它們的共同點(diǎn)根悼。
他們的不同在于。301表示舊地址A的資源已經(jīng)被永久地移除了(這個資源不可訪問了)蜀撑,搜索引擎在抓取新內(nèi)容的同時也將舊的網(wǎng)址交換為重定向之后的網(wǎng)址挤巡;
302表示舊地址A的資源還在(仍然可以訪問),這個重定向只是臨時地從舊地址A跳轉(zhuǎn)到地址B屯掖,搜索引擎會抓取新的內(nèi)容而保存舊的網(wǎng)址玄柏。 SEO302好于301
2)重定向原因:
(1)網(wǎng)站調(diào)整(如改變網(wǎng)頁目錄結(jié)構(gòu));
(2)網(wǎng)頁被移到一個新地址贴铜;
(3)網(wǎng)頁擴(kuò)展名改變(如應(yīng)用需要把.php改成.Html或.shtml)粪摘。
這種情況下,如果不做重定向绍坝,則用戶收藏夾或搜索引擎數(shù)據(jù)庫中舊地址只能讓訪問客戶得到一個404頁面錯誤信息徘意,訪問流量白白喪失;再者某些注冊了多個域名的網(wǎng)站轩褐,也需要通過重定向讓訪問這些域名的用戶自動跳轉(zhuǎn)到主站點(diǎn)等椎咧。
3)什么時候進(jìn)行301或者302跳轉(zhuǎn)呢?
當(dāng)一個網(wǎng)站或者網(wǎng)頁24—48小時內(nèi)臨時移動到一個新的位置,這時候就要進(jìn)行302跳轉(zhuǎn)勤讽,而使用301跳轉(zhuǎn)的場景就是之前的網(wǎng)站因?yàn)槟撤N原因需要移除掉蟋座,然后要到新的地址訪問,是永久性的脚牍。
清晰明確而言:使用301跳轉(zhuǎn)的大概場景如下:
1向臀、域名到期不想續(xù)費(fèi)(或者發(fā)現(xiàn)了更適合網(wǎng)站的域名),想換個域名诸狭。
2券膀、在搜索引擎的搜索結(jié)果中出現(xiàn)了不帶www的域名,而帶www的域名卻沒有收錄驯遇,這個時候可以用301重定向來告訴搜索引擎我們目標(biāo)的域名是哪一個芹彬。
3、空間服務(wù)器不穩(wěn)定叉庐,換空間的時候舒帮。
5、瀏覽器跟蹤重定向地址
現(xiàn)在瀏覽器知道了 "http://www.google.com/"才是要訪問的正確地址眨唬,所以它會發(fā)送另一個http請求会前。這里沒有啥好說的
6好乐、服務(wù)器處理請求
經(jīng)過前面的重重步驟匾竿,我們終于將我們的http請求發(fā)送到了服務(wù)器這里,其實(shí)前面的重定向已經(jīng)是到達(dá)服務(wù)器了蔚万,那么岭妖,服務(wù)器是如何處理我們的請求的呢?
后端從在固定的端口接收到TCP報文開始反璃,它會對TCP連接進(jìn)行處理昵慌,對HTTP協(xié)議進(jìn)行解析,并按照報文格式進(jìn)一步封裝成HTTP Request對象淮蜈,供上層使用斋攀。
一些大一點(diǎn)的網(wǎng)站會將你的請求到反向代理服務(wù)器中,因?yàn)楫?dāng)網(wǎng)站訪問量非常大梧田,網(wǎng)站越來越慢淳蔼,一臺服務(wù)器已經(jīng)不夠用了。于是將同一個應(yīng)用部署在多臺服務(wù)器上裁眯,將大量用戶的請求分配給多臺機(jī)器處理鹉梨。此時,客戶端不是直接通過HTTP協(xié)議訪問某網(wǎng)站應(yīng)用服務(wù)器穿稳,而是先請求到Nginx存皂,Nginx再請求應(yīng)用服務(wù)器,然后將結(jié)果返回給客戶端逢艘,這里Nginx的作用是反向代理服務(wù)器旦袋。同時也帶來了一個好處骤菠,其中一臺服務(wù)器萬一掛了,只要還有其他服務(wù)器正常運(yùn)行疤孕,就不會影響用戶使用娩怎。
如圖所示:通過Nginx的反向代理,我們到達(dá)了web服務(wù)器胰柑,服務(wù)端腳本處理我們的請求截亦,訪問我們的數(shù)據(jù)庫,獲取需要獲取的內(nèi)容等等柬讨,當(dāng)然崩瓤,這個過程涉及很多后端腳本的復(fù)雜操作。由于對這一塊不熟踩官,所以這一塊只能介紹這么多了却桶。
擴(kuò)展閱讀:
1)什么是反向代理?
客戶端本來可以直接通過HTTP協(xié)議訪問某網(wǎng)站應(yīng)用服務(wù)器蔗牡,網(wǎng)站管理員可以在中間加上一個Nginx颖系,客戶端請求Nginx,Nginx請求應(yīng)用服務(wù)器辩越,然后將結(jié)果返回給客戶端嘁扼,此時Nginx就是反向代理服務(wù)器。
7黔攒、服務(wù)器返回一個 HTTP 響應(yīng)
經(jīng)過前面的6個步驟趁啸,服務(wù)器收到了我們的請求,也處理我們的請求督惰,到這一步不傅,它會把它的處理結(jié)果返回,也就是返回一個HTPP響應(yīng)赏胚。
HTTP響應(yīng)與HTTP請求相似访娶,HTTP響應(yīng)也由3個部分構(gòu)成,分別是:
l 狀態(tài)行
l 響應(yīng)頭(Response Header)
l 響應(yīng)正文
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>http</title>
</head>
<body>111</body>
</html>
狀態(tài)行:
狀態(tài)行由協(xié)議版本觉阅、數(shù)字形式的狀態(tài)代碼崖疤、及相應(yīng)的狀態(tài)描述,各元素之間以空格分隔留拾。
格式: HTTP-Version Status-Code Reason-Phrase CRLF
例如: HTTP/1.1 200 OK \r\n
-- 協(xié)議版本:是用http1.0還是其他版本
-- 狀態(tài)描述:狀態(tài)描述給出了關(guān)于狀態(tài)代碼的簡短的文字描述戳晌。比如狀態(tài)代碼為200時的描述為 ok
-- 狀態(tài)代碼:狀態(tài)代碼由三位數(shù)字組成,第一個數(shù)字定義了響應(yīng)的類別痴柔,且有五種可能取值沦偎。如下:
1xx:信息性狀態(tài)碼,表示服務(wù)器已接收了客戶端請求,客戶端可繼續(xù)發(fā)送請求豪嚎。
100 Continue
101 Switching Protocols
2xx:成功狀態(tài)碼搔驼,表示服務(wù)器已成功接收到請求并進(jìn)行處理。
200 OK 表示客戶端請求成功
204 No Content 成功侈询,但不返回任何實(shí)體的主體部分
206 Partial Content 成功執(zhí)行了一個范圍(Range)請求
3xx:重定向狀態(tài)碼舌涨,表示服務(wù)器要求客戶端重定向。
301 Moved Permanently 永久性重定向扔字,響應(yīng)報文的Location首部應(yīng)該有該資源的新URL
302 Found 臨時性重定向囊嘉,響應(yīng)報文的Location首部給出的URL用來臨時定位資源
303 See Other 請求的資源存在著另一個URI,客戶端應(yīng)使用GET方法定向獲取請求的資源
304 Not Modified 服務(wù)器內(nèi)容沒有更新革为,可以直接讀取瀏覽器緩存
307 Temporary Redirect 臨時重定向扭粱。與302 Found含義一樣。302禁止POST變換為GET震檩,但實(shí)際使用時并不一定琢蛤,307則更多瀏覽器可能會遵循這一標(biāo)準(zhǔn),但也依賴于瀏覽器具體實(shí)現(xiàn)
4xx:客戶端錯誤狀態(tài)碼抛虏,表示客戶端的請求有非法內(nèi)容博其。
400 Bad Request 表示客戶端請求有語法錯誤,不能被服務(wù)器所理解
401 Unauthonzed 表示請求未經(jīng)授權(quán)迂猴,該狀態(tài)代碼必須與 WWW-Authenticate 報頭域一起使用
403 Forbidden 表示服務(wù)器收到請求慕淡,但是拒絕提供服務(wù),通常會在響應(yīng)正文中給出不提供服務(wù)的原因
404 Not Found 請求的資源不存在错忱,例如儡率,輸入了錯誤的URL
5xx:服務(wù)器錯誤狀態(tài)碼,表示服務(wù)器未能正常處理客戶端的請求而出現(xiàn)意外錯誤以清。
500 Internel Server Error 表示服務(wù)器發(fā)生不可預(yù)期的錯誤,導(dǎo)致無法完成客戶端的請求
503 Service Unavailable 表示服務(wù)器當(dāng)前不能夠處理客戶端的請求崎逃,在一段時間之后掷倔,服務(wù)器可能會恢復(fù)正常
響應(yīng)頭:
響應(yīng)頭部:由關(guān)鍵字/值對組成,每行一對个绍,關(guān)鍵字和值用英文冒號":"分隔勒葱,典型的響應(yīng)頭有:
響應(yīng)正文
8至非、瀏覽器顯示 HTML
在瀏覽器沒有完整接受全部HTML文檔時钠署,它就已經(jīng)開始顯示這個頁面了,瀏覽器是如何把頁面呈現(xiàn)在屏幕上的呢荒椭?不同瀏覽器可能解析的過程不太一樣谐鼎,這里我們只介紹webkit的渲染過程,下圖對應(yīng)的就是WebKit渲染的過程趣惠,這個過程包括:
解析html以構(gòu)建dom樹 -> 構(gòu)建render樹 -> 布局render樹 -> 繪制render樹瀏覽器在解析html文件時狸棍,會”自上而下“加載,并在加載過程中進(jìn)行解析渲染味悄。在解析過程中隔缀,如果遇到請求外部資源時,如圖片傍菇、外鏈的CSS猾瘸、iconfont等,請求過程是異步的丢习,并不會影響html文檔進(jìn)行加載牵触。
解析過程中,瀏覽器首先會解析HTML文件構(gòu)建DOM樹咐低,然后解析CSS文件構(gòu)建渲染樹揽思,等到渲染樹構(gòu)建完成后,瀏覽器開始布局渲染樹并將其繪制到屏幕上见擦。這個過程比較復(fù)雜钉汗,涉及到兩個概念: reflow(回流)和repain(重繪)。
DOM節(jié)點(diǎn)中的各個元素都是以盒模型的形式存在鲤屡,這些都需要瀏覽器去計算其位置和大小等损痰,這個過程稱為relow;當(dāng)盒模型的位置,大小以及其他屬性,如顏色,字體,等確定下來之后酒来,瀏覽器便開始繪制內(nèi)容卢未,這個過程稱為repain。
頁面在首次加載時必然會經(jīng)歷reflow和repain堰汉。reflow和repain過程是非常消耗性能的辽社,尤其是在移動設(shè)備上,它會破壞用戶體驗(yàn)翘鸭,有時會造成頁面卡頓滴铅。所以我們應(yīng)該盡可能少的減少reflow和repain。
當(dāng)文檔加載過程中遇到j(luò)s文件就乓,html文檔會掛起渲染(加載解析渲染同步)的線程汉匙,不僅要等待文檔中js文件加載完畢拱烁,還要等待解析執(zhí)行完畢,才可以恢復(fù)html文檔的渲染線程盹兢。因?yàn)镴S有可能會修改DOM邻梆,最為經(jīng)典的document.write,這意味著绎秒,在JS執(zhí)行完成前浦妄,后續(xù)所有資源的下載可能是沒有必要的,這是js阻塞后續(xù)資源下載的根本原因见芹。所以我明平時的代碼中剂娄,js是放在html文檔末尾的。
JS的解析是由瀏覽器中的JS解析引擎完成的玄呛,比如谷歌的是V8阅懦。JS是單線程運(yùn)行,也就是說徘铝,在同一個時間內(nèi)只能做一件事耳胎,所有的任務(wù)都需要排隊,前一個任務(wù)結(jié)束惕它,后一個任務(wù)才能開始怕午。但是又存在某些任務(wù)比較耗時,如IO讀寫等淹魄,所以需要一種機(jī)制可以先執(zhí)行排在后面的任務(wù)郁惜,這就是:同步任務(wù)(synchronous)和異步任務(wù)(asynchronous)。
JS的執(zhí)行機(jī)制就可以看做是一個主線程加上一個任務(wù)隊列(task queue)甲锡。同步任務(wù)就是放在主線程上執(zhí)行的任務(wù)兆蕉,異步任務(wù)是放在任務(wù)隊列中的任務(wù)。所有的同步任務(wù)在主線程上執(zhí)行缤沦,形成一個執(zhí)行棧;異步任務(wù)有了運(yùn)行結(jié)果就會在任務(wù)隊列中放置一個事件虎韵;腳本運(yùn)行時先依次運(yùn)行執(zhí)行棧,然后會從任務(wù)隊列里提取事件疚俱,運(yùn)行任務(wù)隊列中的任務(wù)劝术,這個過程是不斷重復(fù)的,所以又叫做事件循環(huán)(Event loop)呆奕。具體的過程可以看這篇文章:點(diǎn)擊這里
9、瀏覽器發(fā)送請求獲取嵌入在 HTML 中的資源(如圖片衬吆、音頻梁钾、視頻、CSS逊抡、JS等等)
其實(shí)這個步驟可以并列在步驟8中姆泻,在瀏覽器顯示HTML時零酪,它會注意到需要獲取其他地址內(nèi)容的標(biāo)簽。這時拇勃,瀏覽器會發(fā)送一個獲取請求來重新獲得這些文件四苇。比如我要獲取外圖片,CSS方咆,JS文件等月腋,類似于下面的鏈接:
圖片:http://static.ak.fbcdn.net/rsrc.php/z12E0/hash/8q2anwu7.gif
CSS式樣表:http://static.ak.fbcdn.net/rsrc.php/z448Z/hash/2plh8s4n.css
JavaScript 文件:http://static.ak.fbcdn.net/rsrc.php/zEMOA/hash/c8yzb6ub.js
這些地址都要經(jīng)歷一個和HTML讀取類似的過程。所以瀏覽器會在DNS中查找這些域名瓣赂,發(fā)送請求榆骚,重定向等等...
不像動態(tài)頁面,靜態(tài)文件會允許瀏覽器對其進(jìn)行緩存煌集。有的文件可能會不需要與服務(wù)器通訊妓肢,而從緩存中直接讀取,或者可以放到CDN中