HTTP 入門體檢

因爲以前太忙了,老是沒有時間把本地寫好的文章梳理整理後發出去。近期有時間了,才慢慢的整理後發出來(本地寫的大多數時候是爲了本身能看,哈哈哈)。html

文章首發於 HTTP 入門體檢ios

不管是大系統仍是小項目,不管是移動端仍是PC端,不管是大數據仍是雲計算,從總體到我的,網絡協議一直都是繞不過去的坎,它在咱們職業生涯中有着舉足輕重的地位。技術浪潮一浪接一浪,不少時候咱們盲目追求新技術卻忘記了新技術的出現都是要依賴於繁瑣複雜且難啃的基層技術,新技術只是爲了更好更快更穩的開發,針對業務需求相對進行了封裝罷了,一層一層剝下來,它仍是原來的它。咱們先來入門一下 HTTP,OSI模型的應用層。git

網絡協議層

網絡有七層協議層:應用層、表示層、會話層、(安全層 - SSL/TLS)、傳輸層、網絡層、數據鏈路層、物理層。因爲表示層跟會話層沒有獨立實現過,而是跟應用層一塊兒實現的github

應用層

應用層決定了向用戶提供應用服務時通訊的活動。(DNS、HTTP、HTTPS、RTMP、FTP);web

傳輸層

傳輸層對上層應用層,提供處於網絡鏈接中的兩臺計算機之間的數據傳輸。(TCP、UDP)。算法

網絡層

網絡層用來處理在網絡上流動的數據包。數據包是網絡傳輸額最小單位。(IP)編程

鏈路層

鏈路層是用來鏈接網絡的硬件部分。包括控制操做系統、驅動、網卡等。瀏覽器

物理層

物理層主要是定義物理設備如何傳輸數據。緩存

栗子

當咱們購物時,會先去 DNS 或 HTTPDNS 查找 IP 地址。知道目標 IP 地址,瀏覽器就會打包請求,若是使用 HTTPS ,則採起加密傳輸。安全

一、應用層:瀏覽器經過 socket 編程,將其打包傳輸給下一層傳輸層; 二、傳輸層:這裏採用TCP協議(PS:它有兩個端口,一個是瀏覽器監聽端口,一個是服務器監聽端口,操做系統每每經過端口來判斷數據包應該往哪一個進程走)。TCP將應用層收到的數據包進行~分割~,並在報文上打上標記序號及端口號轉發給網絡層; 三、網絡層:接收到傳輸層的數據包,在該層有 本地IP地址 以及 目標IP地址,將IP地址封裝後轉發給鏈路層; 四、鏈路層:經過ARP協議,獲取本地MAC地址,發送給網關物理層(默認IP:192.168.1.1)。 5:物理層:因爲有MAC地址,IP 數據包能達到網關。如路由器,會根據路由表,來判斷目標 IP 怎麼走。

IP 地址:指明瞭節點被分配到的地址,可變。 MAC 地址:指網卡所屬的固定地址,基本不變。 IP 間的通訊依賴 MAC 地址。

ARP 協議:解析地址的協議,根據 IP地址 反查出對應的 MAC地址。

HTTP 協議請求報文&響應報文

常見的方法

方法 描述
GET 獲取指定資源,通常來講 GET 請求只用於資源數據的請求。
POST 傳輸實體主體,向指定資源提交數據,如表單提交、資源建立等。
PUT 傳輸資源,向指定資源位置上傳最新內容,如資源更新等。
DELETE 請求服務器刪除置頂的 URI 所標識的資源,簡單來講就是刪除資源。
PATCH 跟 PUT 方法有些相似,都是更新資源。可是 PATCH 主要是更新部分資源, 而 PUT 則是總體更新;當資源不存在時,PATCH 會建立新資源,而 PUT只會 在已有的資源進行更新。
HEAD 同 GET 方法,但 HEAD 經常使用於獲取報文首部,查看服務器性能。
OPTIONS 該方法同 HEAD,可是 OPTIONS 用來詢問服務器返回該資源所支持的方法。

常見狀態碼

狀態碼大類 狀態碼小類 描述
1xx 信息性狀態碼,接收到請求而且繼續處理。
2xx 成功狀態碼。
200 服務器已成功處理了請求。
201 服務器已接收請求,但還沒有處理,客戶端能夠經過該狀態碼進行輪詢。
203 服務器已成功處理了請求,但可能未受權。
204 服務器成功處理了請求,但沒有返回任何內容,如刪除成功。
206 服務器成功處理了部分 GET 請求,如媒體多端請求。
3xx 重定向狀態碼。
301 永久性重定向。
302 臨時性重定向。
303 同302,但多了一個標準,就是明確要求客戶端採用 GET 方法。
注:30一、30二、303 響應後,瀏覽器都會把 POST 改成 GET,並刪除請求主體,等到再次請求時才發送。
304 資源沒有發生變化,該狀態碼跟重定向沒有什麼關係。
4xx 客戶端錯誤狀態碼。
400 請求錯誤,服務器不理解請求的語法,簡單來講就是錯誤的傳參致使的報錯。
401 請求不經過身份驗證,如未登陸或令牌錯誤。
403 請求經過身份驗證,可是未受權,如權限管理越級訪問。
404 請求服務器不存在的資源。
405 請求方法不經過,如該用 POST 方法的請求用了 PUT。
406 請求的資源格式不正確,如請求 JSON 格式數據,服務器只有 XML 格式數據。
409 請求發生衝突,常見於修改內容在服務器上是惟一的,如身份證ID。
410 請求的資源曾經存在過,以下架的視頻。
413 請求體超過服務器的限制,如上傳資源 10M,服務器限制 5M。
414 請求 URI 過長。
415 不支持媒體類型,如上傳 PNG 文件,而服務器規定 JPG。
5xx 服務端錯誤狀態碼。
500 服務器發生錯誤,但緣由未明。
502 網關錯誤,如請求需轉發到B服務器,而B服務器報錯時就會報網關錯誤。
503 服務不可用,服務器重啓或維護之類不在狀態。
504 網關超時,同502,只是B服務器久久不迴應。

HTTP 首部

q,表示權重值,默認值1.0,區間在0~1。如 Accept-Language:zh-CN,en-US;q=0.8,en;q=0.6,表示瀏覽器優先支持 zh-CN 。

通用首部字段

通用首部字段指的是請求報文以及響應報文都會使用到的首部。

  • Cache-Control:經過以下指令,來操做緩存的工做機制。未完待續,篇幅太多,不在這裏贅述,以後給實例。
常見緩存請求指令 說明
no-cache 強制向服務器再次驗證
no-store 不緩存請求或響應的任何內容
max-age=(秒) 響應的最大 Age 值
max-stale=[秒] 接收已過時的響應
min-fresh=(秒) 指望在指定時間內的響應仍有效
常見緩存響應指令 說明
public 可向任意方提供響應的緩存
private 僅向特定用戶返回響應
no-cache 緩存前必須先確認其有效性
no-store 不緩存請求或響應的任何內容
max-age=(秒) 響應的最大 Age 值
s-maxage=(秒) 公共緩存服務器響應的最大 Age 值
must-revalidate 可緩存但必須再向源服務器進行確認
  • Connection:Connection 自己只與當前鏈接有關,當客戶端與服務器之間存在代理,那麼從客戶端的請求報文會逐段發給服務器,服務器也會逐段返回客戶端,一般就算有層層代理請求頭以及響應頭都會**保持原封不動。**可是剛纔提到,Connection 只與當前鏈接有關,那麼在報文轉給下個節點以前刪除,不然就會出現不可預期的問題。其餘不傳遞的 Header 能夠看Connection 的 hop-by-hop
    • Connection: Close:斷開時將 Connection 設置爲Close;
    • Connection: Keep-Alive:鏈接保持持久化;
  • Date:建立報文的日期時間;
  • Pragma:no-cache。指令惟一,爲兼容 HTTP/1.1 以前的版本;
  • Trailer:簡單來講,該字段主要是說明報文末尾記錄了哪些字段;
  • Transfer-Encoding:傳輸編碼方式,如 chunk;
  • Upgrade:升級爲其餘的協議;
Upgrade: TLS/1.0
Connection: Upgrade (必須指定爲Upgrade)
複製代碼

請求首部字段

  • Accept:客戶端能處理的媒體類型,如text/htmlimage/jpeg
  • Accept-Charset:內容支持的字符集,如ios-8895-5,utf-8;q=0.8
  • Accept-Encoding:內容支持的編碼,如gzip,deflate
  • Accept-Language:內容支持的語言,如zh-cn,zh;q=0.7
  • Authorization:認證信息,用來認證用戶的身份;
  • Host:請求資源的服務器,如www.baidu.com
  • If-Match / If-Modified-Since / If-None-Match:參考緩存機制;
  • If-Range:資源未更新時發送實體 Byte 的範圍請求,如 If-Range 字段值如果跟 ETag 值或更新日期時間匹配一致,那麼就做爲範圍請求處理,若不一致,則返回所有資源;
// request body
GET /index.html
If-Range: "123456"
Range: bytes=5001-10000

// response body(匹配狀況下)
206 Partial Content
Content-Range: bytes 5001-10000/1000

// response body(不匹配狀況下)
200 OK
ETag: "45678"
複製代碼
  • Range:獲取部分範圍資源請求,服務器接收後會返回 206 狀態碼;
  • Referer:告知服務器請求的原始資源的 URI;
  • User-Agent:將建立請求的瀏覽器和用戶代理名稱等信息傳送給服務器。
  • Via:用來追蹤客戶端與服務器之間的請求和響應報文的傳輸路徑;
  • Warning:錯誤通知;

響應首部字段

  • Accept-Ranges:bytes 和 none。bytes 是用來告知客戶端,服務器是否能處理範圍請求;
  • Age:告知客戶端,服務器在多久前建立了響應,單位爲秒。若響應的爲緩存服務器,Age 是指緩存後的響應再次發起認證到認證完成的時間
  • ETag:資源的惟一標誌,當資源更新,資源的標誌也會隨之更新;
    • 強ETag:實體發生多麼細微的變化都會改變值;
    • 弱ETag:只有資源發生根本變化,產生差別纔會改變,這時會在開始附加 W/,如:ETag: W/"xxx-1234"
  • Location:將客戶端重定向至指定 URI;
  • Retry-After:對再次發起請求的時機要求,單位秒,常配合狀態碼 503 或 3xx 重定向,如Retry-After: 120
  • Server:當前服務器上的HTTP服務器應用程序信息,如Server: Apache/xxxx (Unix)
  • Vary:可對緩存進行控制,源服務器會向代理服務器傳達關於本地緩存使用方法的命令,簡單來講,就是指定不可緩存的請求頭列表。

實體首部字段

實體首部字段是包含在請求報文和響應報文中的實體部分所使用的首部,用於補充內容的更新時間等與實體相關的信息,這裏主要列舉下響應報文補充字段

  • Allow:用於通知客戶端可以支持 Request-URI 指定資源 的全部 HTTP 方法,當服務器收不到不支持的 HTTP 方法時,會以 405 狀態碼返回。與此同時,還會把全部支持的 HTTP 方法寫入首部字段 Allow 後返回。
  • Content-Encoding:告知客戶端服務器對實體內容的編碼方式,有gzip、compress、deflate、identity;
  • Content-Language:告知客戶端實體內容使用的天然語言,如 zh-cn
  • Content-Length:實體內容的大小(單位字節);
  • Content-Location:返回資源對應的 URI,如訪問 https://www.baidu.com/,返回資源 https://www.baidu.com/index.html
  • Content-Range:範圍請求,如 Content-Range: bytes 5001-10000/10000,單位字節;
  • Content-Type:同 Accept
  • Expires:資源的實效日期,可是假如首部字段 Cache-Control 有指定 max-age 指令時,會優先處理 max-age
  • Last-Modified:資源最後的修改時間;

其餘經常使用響應首部字段 X-

  • X-Frame-Options:控制網站內容在其餘 Web 網站的 Frame 標籤內的顯示問題。DENY爲拒絕;SAMEORIGIN:盡在同源域名下匹配時許可;
  • X-XSS-Protection:針對跨站腳本攻擊的一種對策,0 爲將XSS過濾設置成無效狀態,1 則相反;
  • Content-Security-Policy,X-Content-Security-Policy:內容安全策略,爲了防護XSS、CSRF等代碼注入攻擊,阻止惡意內容在源網頁中執行;
  • X-UA-Compatible:推薦指定的渲染引擎來展現網站內容;

其餘經常使用請求首部字段 X-

  • X-Requested-With:主要用於標識 Ajax 請求。大部分的JavaScript框架會發送這個字段,如 X-Requested-With: XMLHttpRequest
  • DNT:同 X-Do-Not-Track,請求某個網頁應用程序中止跟蹤某個用戶。0 表示 DNT 被禁用,1 則相反;
  • X-Csrf-Token:用於防止 CSRF 攻擊,如 X-Csrf-Token:i8XNjC4b8KVok4uw5RftR38Wgp2BFwql

HTTP 協議通訊

在 HTTP 1.1 以前,每一個 HTTP 請求都要求打開一次 TCP 鏈接,而且使用一次以後就斷開這個 TCP 鏈接,每次這樣都會形成資源的浪費。

持久鏈接

HTTP/1.1 keep-alive:只要任意一端沒有明確提出斷開鏈接,則保持 TCP 鏈接狀態,即在一次 TCP 鏈接中能夠持續發送多份數據而不會斷開鏈接,這樣就能夠減小 TCP 鏈接創建的次數,意味着能夠減小 TIME_WAIT 狀態鏈接。可是,長時間的 TCP 鏈接容易致使系統資源無效佔用,因此正確地設置 keep-alive timeout 時間很是重要。

爲何須要持久鏈接?爲何 TCP 的創建耗費時間?這裏就須要說到 TCP 的三次握手跟四次揮手了。

TCP 三次握手

在客戶端和服務器創建 HTTP 請求的發送和返回的過程當中,在這過程當中是須要建立 TCP Connection,由於 HTTP 只有請求和響應這個概念,而 TCP 起到了傳輸數據包的做用。在 HTTP 1.0 版本,TCP 傳輸完畢以後就關閉了,而在 HTTP 1.1 版本,則 TCP 上面是能夠有多個 HTTP 請求的。

seq(Sequence Number):序列號; ack(Acknowledgement Number):確認序號

  1. SYN=1, seq=X:客戶端發送一個 TCP 的 SYN 標誌位爲1的包,指明客戶端準備鏈接服務器的端口。而 seq,爲初始序列號X,X是隨機的,這樣爲了網絡安全。發送完畢以後客戶端就進入 SYN_SEND 狀態;
  2. SYN=1, ACK=1, seq=y, ack=x+1:服務器返回確認包(SYN=1, ACK=1),同時服務器隨機生成 seq 序列號,並將確認序號 ack 設置爲客戶請求序號加1,即 ack=x+1。完畢以後,服務器進入 SYN_RCVD 狀態;
  3. ACK=1, ack=y+1, seq=x+1:客戶端收到服務器的數據後,會檢查 ack 是否等於 x+1,ACK標誌位爲1。若是正確則會再次發送確認包(ACK=1),而且把服務器發來的 ack 序號在 seq 的基礎上加1,即 ack=y+1,而後再設置 seq=x+1。發送完畢後,客戶端和服務器都進入了 ESTABLISHED 狀態,TCP握手結束。

TCP 四次揮手

關閉TCP鏈接,不管是客戶端仍是服務器,只要執行 close 操做,就能夠發起揮手行爲。之因此有4次,是由於 TCP 鏈接的拆除須要發送4個包。咱們在如下視圖默認爲客戶端向服務器發起 close 操做。其中seq/ack同上。

  1. FIN=1, seq=x:客戶端發送 FIN 包,表示客戶端已經沒有數據能夠發送了,可是仍然能夠接收數據,這時候客戶端進入 FIN+WAIT_1 狀態;
  2. ACK=1, ack=X+1:服務器收到客戶端的 FIN 包,隨後反手就是一個確認包,表示服務器已經收到客戶端關閉鏈接的請求,可是還沒作到真正的關閉;
  3. FIN=1, seq=y:服務器準備關閉鏈接時,再次向客戶端發送結束鏈接的響應。發送完畢以後,服務器進入 LAST_ACK 狀態,等待客戶端最後的確認包ACK
  4. ACK=1, ack=y+1:客戶端收到服務器的結束響應,而後客戶端就發送最後的確認包 ACK,服務器收到後就開始關閉鏈接,進入 CLOSED 狀態;客戶端等待 **2MSL(MSL(Maximum Segment Lifetime): 報文段最大生存時間)**後,再也沒有收到服務器的 ACK,認爲服務器已經正常關閉了,隨後客戶端也關閉鏈接,進入CLOSED 狀態。

HTTPS

不只僅 HTTP,任何未加密的協議都存在如下的不足:

  • 通訊使用不加密明文,內容可能會被竊聽;
  • 不驗證通訊方的身份,有可能遭遇假裝;
  • 沒法證實報文的完整性,因此有可能已遭篡改;

-> HTTP 加密處理 + 認證 + 完整性保護 = HTTPS 在上面提到網絡協議層的時候,有一層是安全層,該層就是 SSL協議/TLS協議。HTTP 是直接與TCP通訊,而HTTPS,則演變成了先和 SSL 通訊,再由 SSL 和 TCP 通訊了。

SSL 還能夠配合其餘應用層協議,如SMTP,Telnet;

HTTPS 加密方式

加密和解密共用一個密鑰稱爲對稱加密,而使用公開密鑰+私有密鑰則爲非對稱加密

HTTPS 則採用對稱加密和非對稱加密二者並用的混合加密機制。由於不管是對稱加密仍是非對稱加密,都是沒法直接保證通訊的安全性,如沒法證實公開密鑰就是貨真價實的。所以須要數字證書認證機構

證書申請流程

  1. 服務器運營人員向數字證書認證機構提出公開密鑰申請
  2. 機構判明申請者的身份後,對公開密鑰作數字簽名,而後將其跟公鑰證書綁定在一塊兒;
  3. 服務器將該公鑰證書發給客戶端,以進行加密通訊;
  4. 客戶端對證書上的數字簽名進行驗證,驗證其有效且信賴

多數瀏覽器開發商發佈版本會事先植入經常使用認證機關的公開密鑰。

通訊機制

  1. Client Hello 報文:包含SSL指定版本、加密組件(Cipher Suite)、列表(密鑰長度、加密算法等);
  2. Server Hello 報文:同 Client Hello 報文,在報文中包含 SSL 版本以及加密組件(篩選自 Client Hello 報文);
  3. Certificate 報文:包含公開密鑰證書;
  4. Client Key Exchange 報文:步驟3的公開密鑰已對該報文進行加密,並含有 Pre-master secret 的隨機字符串;
  5. Change Cipher Spec 報文:該報文會提示服務器,此報文後的通訊採用 Pre-master secret密鑰加密;
  6. Finished 報文:包含鏈接至今爲止的全部校驗值;
  7. 到這一步說明 Finished 報文交換完畢,SSL 鏈接創建完成,開始 HTTP 通訊;

在應用層發送數據時會附加 MAC(Message Authentication Code)的報文摘要來檢查報文是否遭到篡改,從而保護報文的完整性。

安全性在網絡通訊獲得了保證,可是HTTPS也存在HTTPS 處理速度慢(SSL 通訊慢,並且消耗CUP和內存資源)以及證書認證貴 的缺點。

HTTP 1.1 與 HTTP 2

在這裏簡單的說下,相比之下,HTTP 1.1 和 HTTP 2有什麼優化。

HTTP 1.1

  1. 持久鏈接:因爲建立 HTTP 鏈接須要三次握手,而且在每一次請求時須要在客戶端和服務器之間建立 TCP 鏈接, 在服務器返回完內容後,該 TCP 鏈接就關閉,這樣就會致使資源的浪費。所以 HTTP 1.1 的持久鏈接,就會再每一次請求創建完 HTTP 鏈接後不關閉;
  2. pipeline:能夠在同一個鏈接發送多個請求。雖說是能夠發送多個,可是服務器接收處理的邏輯,依舊是並行的,因此返回的數據依舊是須要等待服務器處理完畢再進行下一個的;
  3. 增長了首部字段和方法:如Host首部字段、OPTION請求方法;

HTTP 是一種不保存狀態,即無狀態協議,它不會對請求和響應作持久化處理。所以纔會有了Cookie、Session技術的引進。

Session的實現對Cookie有依賴關係,前者是保存在服務器,由於會佔用服務器CPU和內存資源,可是相對安全;相反的後者是保存在客戶端的,在響應報文內攜帶Set-Cookie首部字段,告知客戶端保存,並且安全性較弱。

HTTP 2

  1. 二進制數據傳輸:在以前的 HTTP 版本,大部分的數據傳輸是字符串,而在 HTTP 2 則會以數據幀來進行傳輸(有點像websocket),這樣同一個鏈接裏的多個請求就不須要按照順序來處理了;
  2. 頭信息壓縮提升效率優化:在 HTTP 1.1版本,每一次的發送跟接收,頭信息都須要完整的返回,所以會佔用服務器資源以及帶寬資源,所以壓縮完後就能夠提升利用率。
  3. 推送:在以前的 HTTP 版本,都是客戶端向服務器發送請求,而在 HTTP 2,服務器也能夠主動的向客戶端發送數據傳輸。

總結

有關網絡協議知識點太多了,在這裏也只是借用巨人的肩膀來簡單的理清網絡協議的大概思路。每個細節,每個原理真真正正要較真起來,均可以單獨寫一篇文章,之因此有這篇文章的存在,是由於後續的文章都須要或多或少的網絡協議知識,也是爲了之後方便本身記憶,不用處處查找資料。這裏的知識點可能會有所紕漏錯誤,也有可能在這裏說得不明不白模糊不清,這以後會慢慢優化補上。

參考

相關文章
相關標籤/搜索