前言
關於HTTP的知識比較繁雜,也比較零散,於是想要通過這篇文章對常用知識點進行總結,一些知識點描述是從網上搜集而來,如有侵權,可以聯繫我進行修改。
提出問題
- Http的報文結構。
- Http request的幾種類型。
- Http的狀態碼含義。
- Http1.1和Http1.0的區別,以及緩存原理
- Http長連接keep-alive。
- Cookie與Session的作用於原理。
- 電腦上訪問一個網頁,整個過程是怎麼樣的:DNS、HTTP、TCP、OSPF、IP、ARP。
解答
1. Http的報文結構
http協議的請求報文和響應報文都是由以下4部分組成:
- 請求行
- 請求頭
- 空行 CR + LF,回車 + 換行
- 請求體
2. Http request的幾種類型
請求行
Request
格式:【方法 URL HTTP版本】 例如: GET /csrfToken HTTP/1.1
HTTP版本:目前有 HTTP/1.0、HTTP/1.1、HTTP/2.0 版本,其中 HTTP1.1 版本使用較廣泛
方法 | 說明 | 支持HTTP協議版本 |
---|---|---|
GET | 獲取資源 | 1.0 、1.1 |
POST | 傳輸實體主體 | 1.0、1.1 |
PUT | 傳輸文件 | 1.0、1.1 |
HEAD | 獲得報文首部 | 1.0、1.1 |
DELETE | 刪除資源 | 1.0、1.1 |
OPTIONS | 詢問支持的方法 | 1.1 |
TRACE | 追蹤路徑 | 1.1 |
CONNECT | 要求用隧道協議連接代理 | 1.1 |
LINK | 建立和資源之間的聯繫 | 1.0 |
UNLINK | 斷開連接關係 | 1.0 |
Response
格式:【HTTP版本 狀態碼 描述】 例如: HTTP/1.1 200 OK
、HTTP/1.1 404 NOT FOUND
類別 | 原因短語 | |
---|---|---|
1xx | Informational(信息性狀態碼) | 接收的請求正在處理 |
2xx | Success(成功狀態碼) | 請求正常處理完畢 |
3xx | Redirection(重定向狀態碼) | 需要進行附加操作以完成請求 |
4xx | Client Error(客戶端錯誤狀態碼) | 服務器無法處理請求 |
5xx | Server Error(服務器錯誤狀態碼) | 服務器處理請求出錯 |
3. Http的狀態碼含義
常用狀態碼
- 200:OK,請求被正常處理
- 204:No Content,請求被受理但沒有資源可以返回,返回204響應,瀏覽器顯示的頁面不發生更新
- 206:Partial Content,客戶端進行範圍請求,服務器成功執行了這部分的GET請求,響應報文中包含由Content-Range指定範圍的實體內容
- 301:Moved Permanently,永久性重定向,比如訪問
http://test.zhixue.com/zbptadmin
,服務器會返回301,response的headers中會包含一個字段:Location: http://test.zhixue.com/zbptadmin/
,瀏覽器會按照這個地址重新請求,並且如果用戶保存了書籤,瀏覽器會自動按照Location更新書籤 - 302:Found,臨時性重定向,和301類似,但是瀏覽器不會更新書籤
- 303:See Other,和302類似,但303明確表示客戶端應該使用GET方法獲取Location資源
- 備註:當301,302,303響應狀態碼返回時,幾乎所有的瀏覽器都會把POST改成GET,並刪除請求報文內的主體,之後請求會自動再次發送。301,302標準是禁止將POST方法改成GET方法的,但實際使用時瀏覽器廠商都會這麼做。
- 304:Not Modified,發送附帶條件的請求時,(附帶條件的請求是指採用GET方法的請求報文中包含If-Match,If-Modified-Since,If-None-Match,If-Range,If-Unmodified-Since中任一首部),條件不滿足返回304,可直接使用客戶端緩存,與重定向無關
- 307:Temporary Redirect,臨時重定向,與302類似,只是強制要求使用POST方法
- 400:Bad Request,請求報文中存在語法錯誤,服務器無法識別
- 401:Unauthorized,請求需要認證
- 403:Forbidden,請求對應的資源禁止被訪問
- 404:Not Found,服務器無法找到對應資源
- 500:Internal Server Error,服務器內部錯誤
- 503:Service Unavailable,服務器正忙
常見HTTP首部字段
通用首部字段(請求報文與響應報文都會使用的首部字段)
- Date:創建報文的時間
- Connection:連接的管理
- Cache-Control:緩存的控制
- Transfer-Encoding:報文主題的傳輸編碼方式
請求首部字段(請求報文會使用的首部字段)
- Host:請求資源所在的服務器
- Accept:可處理的媒體類型
- Accept-Charset:可接收的字符集
- Accept-Encoding:可接收的內容編碼
- Accept-Language:可接收的自然語言
響應首部字段(響應報文會使用的首部字段)
- Accept-Range:可接收的字節範圍
- Location:讓客戶端重定向到的URI
- Server:HTTP服務器的安裝信息
實體首部字段(請求報文與響應報文的實體部分使用的首部字段)
- Allow:資源可支持的HTTP方法
- Content-Type:實體主類的類型
- Content-Encoding:實體主體適用的編碼方式
- Content-Language:實體主體的自然語言
- Content-Length:實體主體的字節數
- Content-Range:實體主體的位置範圍,一般用於發出部分請求時使用
4. HTTP1.0、HTTP1.1、HTTP2.0區別
HTTP1.0 和 HTTP1.1 主要區別
-
長連接
- HTTP1.0需要使用keep-alive參數告知服務器要建立一個長連接,而HTTP1.1默認支持長連接
- HTTP是基於TCP/IP協議的,創建一個TCP連接是需要經過三次握手的,有一定的開銷,如果每次通訊都要重新建立連接的話,對性能有影響。因此最好能維持一個長連接,可以用這個長連接來發送多個請求
-
節約帶寬
- HTTP1.1支持只發送header信息,也就是HTTP的HEAD Method,如果服務器認爲客戶端有權限請求服務器,則返回100,否則返回401。客戶端如果接收到100,纔開始把請求體body發送到服務器。
- 這樣,當服務器返回401的時候,客戶端就可以不用發送請求體了,節約了帶寬
- HTTP1.1支持分塊傳輸,比如206狀態碼,由Content-Range指定傳輸內容,這是支持文件斷點續傳的基礎。
-
HOST域
- 現在一臺服務器上可以有多個虛擬主機,這些虛擬站點可以共享同一個ip和端口,HTTP1.0是沒有host域的,HTTP1.1才支持這個參數
HTTP1.1 和 HTTP2.0的區別
-
多路複用
-
HTTP2.0使用了多路複用的技術,做到同一個連接併發處理多個請求,而且併發請求的數量比HTTP1.1大了好幾個數量級
- 當然HTTP1.1也可以多建立幾個TCP連接,來支持處理更多併發的請求,但是創建TCP連接本身也是有開銷的
- TCP連接有一個預熱和保護的過程,先檢查數據是否傳送成功,一旦成功過,則慢慢加大傳輸速度。因此對應瞬時併發的連接,服務器的響應就會變慢。所以最好能使用一個建立的連接,並且這個連接可以支持瞬時併發的請求
- HTTP/1.1,若干個請求排隊串行化單線程處理,後面的請求等待前面請求的返回才能獲得執行機會,一旦有某個請求超時,後續請求只能被阻塞,也就是人們常說的線頭阻塞
- HTTP/2.0,多個請求可同時在一個連接上並行執行,某個任務耗時嚴重,不會影響到其他連接的正常執行
-
-
數據壓縮
- HTTP1.1不支持header數據的壓縮,HTTP2.0使用HPACK算法對header的數據進行壓縮,這樣數據體積小了,在網絡上傳輸就會更快
-
服務器推送
- 當我們對HTTP2.0的web server請求數據的時候,服務器會順便把一些客戶端需要的資源一起推送到客戶端,免得客戶端再次創建連接發送請求到服務器獲取。這種方式非常適合加載靜態資源。
- 服務器推送的這些資源其實存在客戶端的某個地方,客戶端直接從本地加載這些資源就可以了,不用走網絡,速度自然快很多。
HTTP緩存
緩存分類
- 強緩存
瀏覽器在加載資源時,先根據這個資源的一些http header判斷它是否命中強緩存,如果命中,瀏覽器直接從自己的緩存中讀取資源,不會發請求到服務器,此時狀態碼是200,但是看Size項是from memory cache或from disk cache
- 協商緩存
- 當強緩存沒有命中時,瀏覽器一定會發送一個請求到服務器,通過服務器端依據資源的另外一些http header驗證這個資源是否命中協商緩存,如果命中,服務器會將這個請求返回304,但是不會返回這個資源的數據,而是告訴客戶端可以直接從緩存中加載這個資源,於是瀏覽器就又會從自己的緩存中去加載這個資源;如果沒有命中,則將資源返回客戶端,狀態爲200,瀏覽器同時依據response header中的相關項更新本地緩存數據
from memory cache 和 from disk cache
區別
- from memory cache 是從內存中讀取緩存資源,很快,關閉瀏覽器後,內存中的資源就消失了
- from disk cache 是從磁盤中讀取緩存資源,要比 from memory cache 慢,但是持久化,關閉瀏覽器後仍然存在
哪些資源存在memory,哪些資源存在disk
看了一些文章,大部分觀點是說:
- 資源在disk和memory中都會存
- 當關閉瀏覽器,再打開那個頁面的時候,從disk cache中獲取緩存資源,同時將緩存資源存在了內存中,當再次刷新頁面的時候,就從memory cache中讀取,因爲這樣會更快一些
- 我自己試了一些頁面,再次刷新還是有的from disk cache,有的from memory cache,所以這個持保留觀點
- 還有的文章說css文件存在disk中,js等腳本存在memory中,個人認爲這個不太靠譜,因爲memory中的緩存在關閉瀏覽器就消失了,如果js只存在memory,就起不到緩存的作用了
強緩存相關http header
- Expires
Expires的值是服務端返回的到期時間,用GMT格式的字符串表示,如:Expires: Thu, 31 Dec 2016 23:55:55 GMT
。即下一次請求時,請求時間小於服務器返回的到期時間,直接使用緩存數據。不過Expires是HTTP1.0的東西,現在瀏覽器默認使用HTTP1.1,所以它的作用基本忽略。另一個問題是,到期時間是由服務器生成的,但是客戶端時間可能和服務器時間有偏差,這就會導致緩存命中的誤差。所以HTTP1.1的版本中,使用Cache-Control替代。
- Cache-Control
Cache-Control是最重要的規則。常見的取值有:
- ```private```:客戶端可以緩存
- ```public```:客戶端和代理服務器都可以緩存
- ```max-age=xxx```:緩存的內容將在xxx秒後失效,單位是秒
- ```no-cache```:需要使用**協商緩存**來驗證緩存數據
- ```no-store```:不緩存
協商緩存相關http header
第1組:Last-Modified/If-Modified—Since
-
Last-Modified
:第一次請求資源時,服務器返回的http header,告訴瀏覽器資源的最後修改時間,爲GMT格式,如Last-Modified: Thu, 24 Jan 2017 23:55:55 GMT
-
If-Modified-Since
:再次請求服務器資源時,瀏覽器設置在請求header中,值 爲該資源第一次請求時服務器設置的Last-Modified
`值,如
`If-Modified-Since: Thu, 24 Jan 2017 23:55:55 GMT
`,服務器收到請求後發現request header中有
`If-Modified-Since
`,則與被請求資源的最後修改時間進行比對。若資源的最後修改時間大於
`If-Modified-Since
`,說明資源又被改動過,則返回資源內容,狀態碼200,同時瀏覽器依據相應response header更新緩存資源;若資源的最後修改時間小於或等於
`If-Modified-Since
``,說明資源無新修改,則返回狀態碼304,但是不返回資源,告知瀏覽器繼續使用所保存的cache
第2組:Etag/If-None-Match
-
Etag
:服務器響應請求時,告訴瀏覽器當前資源在服務器的唯一標識(生成規則由服務器確定),如Etag: W/"5886c231-8d9"
-
If-None-Match
:再次請求服務器時,通過此字段告知服務器該資源的唯一標識,如If-None-Match: W/"5886c231-8d9"
,服務器收到請求後發現request header中有If-None-Match
,則與被請求資源的唯一標識進行比對,若不同,說明資源又被改動過,則返回資源內容,狀態碼200,同時瀏覽器依據相應response header更新緩存資源;若相同,則說明資源無更改,返回304,告知瀏覽器繼續使用所保存的緩存資源
總結
- 先執行強緩存策略,服務器通知瀏覽器一個緩存有效時間,在有效時間內,下次請求時直接使用緩存,不發起http請求,緩存從from memory cache或from disk cache中讀取,若超過了有效時間,則執行協商緩存策略
- 對於協商緩存,將緩存信息中的Etag和Last-Modified的值通過If-None-Match和If-Modified-Since發送給服務器,由服務器進行校驗,若資源無更改,返回304,瀏覽器繼續使用緩存,若資源被更改,則返回資源,狀態碼200,同時瀏覽器更新緩存
流程圖
瀏覽器第一次請求:
瀏覽器第二次請求:
5. Http長連接keep-alive
三個概念
- 短連接
所謂短連接,就是每次請求一個資源就建立連接,請求完成後立馬關閉。每次請求都經過“創建TCP連接 -> 請求資源 -> 響應資源 -> 釋放連接”。
- 長連接
所謂長連接(persistent connection),就是隻建立一次TCP連接,多次HTTP請求都複用該連接。
- 並行連接
所謂並行連接(multiple connection),其實就是併發的短連接。
keep-alive
在HTTP/1.0裏,爲了實現client到web-server能支持長連接,必須在HTTP請求頭裏顯式指定Connection: keep-alive
在HTTP/1.1裏,就默認開啓了keep-alive,要關閉keep-alive必須在HTTP請求頭裏顯式指定Connection: close
現在大多數瀏覽器都默認是使用HTTP/1.1,所以keep-alive都是默認打開的。一旦client和server達成協議,那麼長連接就建立好了。
keepalive_timeout
Httpd守護進程,一般都提供了keep-alive timeout時間設置參數。比如nginx的keepalive_timeout,和Apache的KeepAliveTimeout。這個keepalive_timout時間值意味着:一個http產生的tcp連接在傳送完最後一個響應後,還需要hold住keepalive_timeout秒後,纔開始關閉這個連接。Nginx配置中的keepalive_timeout默認爲75s,
6. cookie與Session
這個重點在於理解,這裏就不贅述了。
7. 網頁經歷了什麼
這個東西很多,後面會專門寫一篇文章來進行說明。