小編是一個非典型面試官,對於HTTP協議的第一個問題,一般人會問常用的狀態碼有哪些。小編不這麼問,小編的問題是HTTP的全稱是什麼,把英語給我說出來!
HTTP的全稱是什麼?
超文字傳輸協議,HyperText Transfer Protocol,這幾個單詞可別發走音了。所謂的超文字就是帶標記的文字,剛開始的時候是指HTML。現在HTTP協議傳輸的東西可不只是HTML了,什麼表單啊JSON啊XML啊檔案啊都可以傳輸。
HTTP常用的狀態碼有哪些?
大部分同學都知道200、404、500、302狀態碼。如果連404都不知道,是要被小編鄙視的。500錯誤為什麼這麼常見呢,因為在開發的時候老是出bug,一個大異常丟擲來,瀏覽器就500了。500表示InternalServerError,也就是內部伺服器錯誤,如果不是bug,一般就是資料庫掛了。
再多問幾個狀態碼很多人就不知道了,因為大多數公司的軟體服務沒有走標準的HTTP狀態碼,很多狀態碼從來就不會出現,同學們自然也不會知道。
400 Bad Request 用於引數驗證,少了一個引數或者引數型別錯誤之類的。
502 Bad Gateway 後端服務掛掉或者壓力過大的時候, Nginx接到的請求無法及時傳遞給後端的服務進行處理,這個時候就會出現502錯誤。這個也非常常見,知乎豆瓣網站經常開小差的時候發生的錯誤就是這個。
304 Not Modified 極少人知道這個狀態碼,因為大部分後端開發者的前端Javascript開發經驗都嚴重不足。當你用Chrome開啟一個經常訪問的網站,看看Network傳輸的靜態資源就可以看到很多304狀態碼。它表示該資源被瀏覽器快取了不需要重新請求伺服器。
401 Unauthorized 許可權不足,這個很好理解,就是資源存在但是不讓你訪問。
403 Forbidden 資源禁止訪問,如果你的IP列為黑名單了,就會發生這種錯誤。
其實還有很多狀態碼,小編也沒去好好研究了,因為實在不會在工作中用到。感興趣的請繼續閱讀維基百科
HTTP有哪些Method?
GET 不解釋,如果讀者不知道,建議別在IT圈混了。
POST 一般用於建立或者修改資源,在RESTFUL規範裡面POST只用來建立資源,並返回201 Created狀態碼錶示建立成功。不過大多數網站都不遵循嚴格的RESTFUL規範,POST拿來做修改資源的事也是非常常見的。
PUT 對應於POST表示建立資源,PUT用於修改資源,PUT的引數必須是物件的全部屬性,修改是覆蓋式全部修改。
PATCH 對應於PUT的引數是物件的全部屬性,PATCH的引數是部分屬性,修改是區域性欄位修改。
DELETE 用於刪除資源。
HEAD 不常用,跟GET差不多,區別就是不返回Body內容,只返回HTTP頭資訊。一般用於獲取資源的元資訊,比如長度,修改時間等
OPTIONS 跨域相關,後面再講。
TRACE 小編沒用過。
CONNECT 小編沒用過。
後面三個感興趣的去閱讀一下RPC規範。小編大概看了一下,表示沒怎麼看懂,你行你上去挑戰一下。
HTTP協議格式是怎樣的?
HTTP的請求和響應的訊息協議是一樣的,分為三個部分,起始行、訊息頭和訊息體。這三個部分以CRLF作為分隔符。最後一個訊息頭有兩個CRLF,用來表示訊息頭部的結束。
HTTP請求的起始行稱為請求行,形如GET /index.html HTTP/1.1
HTTP響應的起始行稱為狀態行,形如200 ok
訊息頭部有很多鍵值對組成,多個鍵值對之間使用CRLF作為分隔符,也可以完全沒有鍵值對。形如Content-Encoding: gzip
訊息體是一個字串,字串的長度是由訊息頭部的Content-Length鍵指定的。如果沒有Content-Length欄位說明沒有訊息體,譬如GET請求就是沒有訊息體的,POST請求的訊息體一般用來放置表單資料。GET請求的響應返回的頁面內容也是放在訊息體裡面的。我們平時呼叫API返回的JSON內容都是放在訊息體裡面的。
什麼是分塊傳送?
當瀏覽器向伺服器請求一個資源時,這個資源是一個動態資源,伺服器無法提前預知資源的大小,這個時候就可以使用分塊傳輸。
伺服器先生成一個thunk,傳送這個chunk,再生成一個chunk,再傳送一個chunk,直到全部資源傳送完成。
分塊傳送需要在請求頭增加一個特殊的鍵值對transfer-encoding: thunked,那麼訊息體的內容便是分塊傳送的。
chunked傳輸格式如圖所示,由一段一段的分塊組合而成,每個塊由一個長度行和一個分塊體組成,最後一個分塊長度為0表示結束。
持久連線的機制是怎樣的?
HTTP早期版本中每個請求都會發起一個連線,一個網頁除了頁面的HTML之外還會有很多靜態資源以及諸多的API呼叫,如果每個請求都一個連線,勢必網頁的一次載入就會和伺服器建立多次連線,這是非常浪費伺服器資源的,同時也讓客戶端的訪問速度慢了不少。HTTP1.0之後引入了Keep-Alive持久連線,在HTTP1.1版本中成為預設選項。它使得HTTP的一個連線可以連續服務多個請求,有效節省了資源,增加了客戶端頁面的載入速度。
持久連線也不宜一直保持,畢竟每個連線都會佔用伺服器資源,如果開啟網頁的人太多,那伺服器資源也會緊張,所以一般伺服器都會配置一個KeepAlive Timeout引數和KeepAlive Requests引數限制單個連線持續時長和最多服務的請求次數。
如果伺服器設定的timeout時長為0,就退化到非持久連線。非持久連線會在響應頭部增加一個頭資訊Connection: Close通知客戶端在接受完當前響應後連線需要立即關閉。
同樣瀏覽器也不會因為伺服器將KeepAlive Timeout配置了無限長就不管不問一直持續保持連線。每個瀏覽器都有它自己的內建限制,具體限制瀏覽器廠商各有不同。
什麼叫Pipeline管線化?
HTTP1.0不支援管線化,同一個連線處理請求的順序是逐個應答模式,處理一個請求就需要耗費一個TTL,也就是客戶端到伺服器的往返時間,處理N個請求就是N個TTL時長。當頁面的請求非常多時,頁面載入速度就會非常緩慢。
從HTTP1.1開始要求伺服器支援管線化,可以同時將多個請求傳送到伺服器,然後逐個讀取響應。這個管線化和Redis的管線化原理是一樣的,響應的順序必須和請求的順序保持一致。
如何理解HTTP協議的無狀態性?
所謂HTTP協議的無狀態性是指伺服器的協議層無需為不同的請求之間建立任何相關關係,它特指的是協議層的無狀態性。但是這並不代表建立在HTTP協議之上的應用程式就無法維持狀態。應用層可以通過會話Session來跟蹤使用者請求之間的相關性,伺服器會為每個會話物件繫結一個唯一的會話ID,瀏覽器可以將會話ID記錄在本地快取LocalStorage或者Cookie,在後續的請求都帶上這個會話ID,伺服器就可以為每個請求找到相應的會話狀態。
閱讀相關文章,關注公眾號【碼洞】