關於http和一次完整的前後端響應
首先說下寫下這個的初心,最近專案遇見一個很奇怪的bug,當我的非同步請求發出的時候,在chrome上面可以看到request和responed相應的條目,但是當你開啟responsed的時候發現裡面的Preview和Response裡面是空白,但是我的非同步方法的回掉函式是有資料的。
這時候瀏覽器會直接崩潰,在工作管理員中你會發現chrome的大小一直在增長。直到chrome崩潰
1. 當我們在瀏覽器的urlh中輸入網址的時候,瀏覽器會做的事情
- 域名解析(eg:www.biying.com)
- 發起TCP的3次握手
- 建立TCP連線後發起http請求
- 伺服器響應http請求,得到html(HTML樹)
- 瀏覽器解析html程式碼,並請求html程式碼中的資源
- 瀏覽器對頁面進行渲染呈現給使用者(渲染頁面)
- 域名解析(我們以chrome為例)當我們請求網址的也就是對應的伺服器名
chrome首先搜尋自身的DNS快取(快取時間比較短,大概只有1分鐘,且只能容納1000條快取)看自身有沒有對應條目的而且沒有過期,如果有且沒有過期則解析到此結束。
如果瀏覽器自身的快取裡面沒有找到對應的條目,那麼chrome會搜尋作業系統自身的DNS快取,如果找到且沒有過期則停止搜尋解析到此結束
如果在Windows系統的DNS快取也沒有找到,那麼嘗試讀取hosts檔案(位於C:\Windows\System32\drivers\etc),看看這裡面有沒有該域名對應的IP地址,如果有則解析成功(實話實說在開發的時候,你真的需要在這檔案裡面配上你所訪問的ip和域名要一一對應)
這個時候尋找域名的工作就交給internet了(後面的步驟。。。)
-
發起TCP的3次握手(劃重點,要考)
Client首先傳送一個連線試探,ACK=0 表示確認號無效,SYN = 1 表示這是一個連線請求或連線接受報文,同時表示這個資料包不能攜帶資料,seq = x 表示Client自己的初始序號(seq = 0 就代表這是第0號包),這時候Client進入syn_sent狀態,表示客戶端等待伺服器的回覆
Server監聽到連線請求報文後,如同意建立連線,則向Client傳送確認。TCP報文首部中的SYN 和 ACK都置1 ,ack = x + 1表示期望收到對方下一個報文段的第一個資料位元組序號是x+1,同時表明x為止的所有資料都已正確收到(ack=1其實是ack=0+1,也就是期望客戶端的第1個包),seq = y 表示Server 自己的初始序號(seq=0就代表這是伺服器這邊發出的第0號包)。這時伺服器進入syn_rcvd,表示伺服器已經收到Client的連線請求,等待client的確認。
Client收到確認後還需再次傳送確認,同時攜帶要傳送給Server的資料。ACK 置1 表示確認號ack= y + 1 有效(代表期望收到伺服器的第1個包),Client自己的序號seq= x + 1(表示這就是我的第1個包,相對於第0個包來說的),一旦收到Client的確認之後,這個TCP連線就進入Established狀態,就可以發起http請求了。
舉個例子: 假設一個老外在故宮裡面迷路了,看到了小明,於是就有下面的對話:
- 老外: Excuse me,Can you Speak English?
- 小明: yes 。
- 老外: OK,I want ...
其次就是2個計算機通訊是靠協議(目前流行的TCP/IP協議)來實現,如果2個計算機使用的協議不一樣,那是不能進行通訊的,所以這個3次握手就相當於試探一下對方是否遵循TCP/IP協議,協商完成後就可以進行通訊了,當然這樣理解不是那麼準確。
2. http請求的時候一次完整的請求過程
進過TCP3次握手之後,瀏覽器發起了http的請求,使用的http的方法 ,請求的URL ,請求協議
- 請求方式:
我們所說的get/post/...其他的現在基本用不到
- 請求協議
- http/0.9: stateless
- http/1.0: MIME, keep-alive (保持連線), 快取
- http/1.1: 更多的請求方法,更精細的快取控制,持久連線(persistent connection) 比較常用
- 請求頭部
- Accept 就是告訴伺服器端,我接受那些MIME型別
- Accept-Encoding 這個看起來是接受那些壓縮方式的檔案
- Accept-Lanague 告訴伺服器能夠傳送哪些語言
- Connection 告訴伺服器支援keep-alive特性
- Cookie 每次請求時都會攜帶上Cookie以方便伺服器端識別是否是同一個客戶端
- Host 用來標識請求伺服器上的那個虛擬主機,比如Nginx裡面可以定義很多個虛擬主機, 那這裡就是用來標識要訪問那個虛擬主機。
- User-Agent 使用者代理,一般情況是瀏覽器,也有其他型別,如:wget curl 搜尋引擎的蜘蛛等
- 請求狀態
- 1xx: 資訊性狀態碼
- 100, 101
- 2xx: 成功狀態碼
- 200:OK
- 3xx: 重定向狀態碼
- 301: 永久重定向, Location響應首部的值仍為當前URL,因此為隱藏重定向;
- 302: 臨時重定向,顯式重定向, Location響應首部的值為新的URL
- 304:Not Modified 未修改,比如本地快取的資原始檔和伺服器上比較時,發現並沒有修改,伺服器返回一個304狀態碼, 告訴瀏覽器,你不用請求該資源,直接使用本地的資源即可。
- 4xx: 客戶端錯誤狀態碼
- 404: Not Found 請求的URL資源並不存在
- 5xx: 伺服器端錯誤狀態碼
- 500: Internal Server Error 伺服器內部錯誤
- 502: Bad Gateway 前面代理伺服器聯絡不到後端的伺服器時出現
- 504:Gateway Timeout 這個是代理能聯絡到後端的伺服器,但是後端的伺服器在規定的時間內沒有給代理伺服器響應
基本上我所理解的http和請求就是這樣,當然我在頭部寫到的問題覺得是服務端的人員需要解決的問題而不是前端開發所需要解決的。
感謝這篇部落格的作者提供的文章原文