HTTP全解析

lvzishen發表於2019-03-12

一.Http是什麼?

中文名稱--超文字傳輸協議,是TCP/IP協議族的最頂層-應用層。應用層協議的產生只是為了C/S雙方都能看懂資料,是對傳輸資料的包裝。

二.Http請求格式

URL格式分為三部分: 協議型別://伺服器地址(和埠號)/路徑(Path) https://segmentfault.com/write?freshman=1

三.Http的報文格式

1.請求:

HTTP全解析

  • 請求報文---->分為 : 請求行,Header,Body三部分。
  • 請求行中包括請求的方式(GET,POST等),請求的路徑(主機地址之後的部分),Http的版本號
  • 請求頭包括一些上傳資訊的屬性,是固定名稱的鍵值對形式,最後一個請求頭之後是一個空行,這個行非常重要,它表示請求頭已經結束,接下來的是請求正文。
  • 請求體是上傳的內容,一般配合請求頭Content-Type為 x-www-form-urlencoded的形式使用(表單格式),GET請求沒有請求體。

2.響應:

HTTP全解析

  • 響應報文---->分為:響應行,Header,Body三部分。
  • 響應行中包括Http版本號,響應狀態碼和響應狀態資訊三部分。
  • 響應體根據伺服器返回的資料格式為主,一般響應體都是返回JSON格式。

四.請求方法:列舉常見的5種

理論上講 GET POST 除了這兩個詞不一樣之外沒有任何區別。區別都是客戶端的約定俗成,以下均是在HTTP以標準規範使用的情況下為基礎。

GET

  • 用於直接從伺服器上獲取資源。
  • 對伺服器資料不進行修改,滿足冪等性(反覆呼叫多次時會得到相同的結果。例如執行十次相同的GET請求相當於從伺服器獲取十次資料,但並不會對伺服器資料造成修改)。 不傳送Body請求體。
GET  /users/1  HTTP/1.1 

Host: api.github.com
複製程式碼

POST

  • 用於增加或修改伺服器上的資源。
  • 傳送給伺服器的內容寫在Body中。
  • 不滿足冪等性(增加資源的時候執行一次和執行十次不同,執行一次增加一個,執行十次增加十個)。
POST /users HTTP/1.1    
                                               
Host: api.github.com 
Content-Type: application/x-www-form-urlencoded  (Content-Type為 “application/x-www-form-urlencoded”時,才會讀取Body中的內容)
Content-Length: 13 

name=lvzishen&gender=male     
複製程式碼

PUT

  • 用於修改伺服器上的資源(和POST請求功能有些重複了,POST既能新增又能修改資源,PUT只能修改資源)。
  • 傳送給伺服器的內容寫在Body中。
  • 滿足冪等性。
PUT /users HTTP/1.1            
                                       
Host: api.github.com 
Content-Type: application/x-www-form-urlencoded  (Content-Type為 “application/x-www-form-urlencoded”時,才會讀取Body中的內容)
Content-Length: 13 

name=lvzishen&gender=male
複製程式碼

DELETE

  • 用於刪除伺服器上的資源。
  • 不傳送BODY。
DELETE /users/1 HTTP/1.1 

Host: api.github.com
複製程式碼

HEAD

  • 和GET請求一樣都是從獲取資源(和GET請求不同的是響應資料中沒有BODY)。
  • 一般可以用於下載檔案,比如先用HEAD請求去看是否支援伺服器是否支援分段下載功能,如果支援再用GET或POST請求配置相應分段傳輸的資料去下載獲取資源,避免無用的資源浪費。檢查資源的有效性(如先用HEAD拉去獲取ACCEPT RANGE總長度,再用GET請求配合RANGE去下載部分內容)。
HEAD  /users/1  HTTP/1.1 

Host: api.github.com
複製程式碼

五.Status Code狀態碼

用於對相應結果作出型別化描述。

  • 1xx:臨時性訊息。如:100 (繼續傳送)、101(正在切換協議)
  • 2xx:成功。最典型的是 200(OK)、201(建立成功)。
  • 3xx:重定向。如 301(永久移動)、302(暫時移動)、304(內容未改變)。 301表示搜尋引擎在抓取新內容的同時也將舊的網址交換為重定向之後的網址;302表示舊地址A的資源還在(仍然可以訪問),這個重定向只是臨時地從舊地址A跳轉到地址B,搜尋引擎會抓取新的內容而儲存舊的網址(瀏覽器快取的地址)。
  • 4xx:客戶端錯誤。如 400(客戶端請求錯誤)、401(認證失敗)、403(被禁止)、404(找不到內容)。  401配合Authorization,403比如IP被禁止,404比如傳的URL錯誤
  • 5xx:伺服器錯誤。如 500(伺服器內部錯誤)。

六.Header

1.Header是什麼? HTTP訊息的 metadata(後設資料)。

2.什麼是後設資料? 通俗的講就是資料的屬性。以一個登入介面為例,使用者名稱密碼是上傳的資料(放在BODY中),那麼使用者名稱密碼的長度( Content-Length)、以什麼型別( Content-Type )上傳等等就是它的後設資料。

幾個重要的Header

1.Host

目標主機。注意:不是在網路上用於定址(定址用DNS)的,而是在目標伺服器(找到IP後一個IP下有可能有多個主機名,確定訪問的是哪一個主機)上用於定位子伺服器的。

2.Content-Type

指定Body的型別。主要分為四類:

(1). text/html: 請求 Web 頁面是返回響應的型別,Body 中返回 html文字。格式如下:

HTTP/1.1 200 OK 

Content-Type: text/html;charset=utf-8 
Content-Length: 853 ......

<!DOCTYPE html>
<html>
<head>
     <meta charset="utf-8">
.....
複製程式碼

(2). x-www-form-urlencoded : 純文字表單的提交方式(只有以表單形式提交時,才會讀取Body中的內容)。 格式如下:

POST /users HTTP/1.1

Host: api.github.com 
Content-Type: application/x-www-form-urlencoded 
Content-Length: 27 

name=lvzishen&gender=male
複製程式碼

對應 Retrofit 的程式碼:

@FormUrlEncoded      <--代表的是以普通表單(application/x-www-form-urlencoded)上傳文字引數,加了這個註解後才會讀取@Field中的引數,因為@Field最後會轉變為請求體Body中的內容.
@POST("/users") 
Call addUser(@Field("name") String name, @Field("gender") String gender);
複製程式碼

(3).multipart/form-data :頁面含有二進位制檔案時的提交方式(上傳檔案或文字都可以,但是一般沒有用此上傳純文字,因為會多加如boundary、分隔符等字元,浪費流量和頻寬)。(只有以表單形式提交時,才會讀取Body中的內容)。 格式如下:

POST /users HTTP/1.1 
Host: hencoder.com 
Content-Type: multipart/form-data; boundary=----        boundary為起始點
WebKitFormBoundary7MA4YWxkTrZu0gW 
Content-Length: 2382 

------WebKitFormBoundary7MA4YWxkTrZu0gW                 WebKitFormBoundary7MA4YWxkTrZu0gW<--為分隔符
Content-Disposition: form-data; name="name" 

rengwuxian 
------WebKitFormBoundary7MA4YWxkTrZu0gW 
Content-Disposition: form-data; name="avatar"; filename="avatar.jpg" 
Content-Type: image/jpeg 

JFIFHHvOwX9jximQrWa......
複製程式碼

(4). application/json , image/jpeg , application/zip ...

單項內容(文字或非文字都可以),用於 Web Api 的響應或者 POST / PUT 的請求 請求中提交 JSON:

POST /users HTTP/1.1

Host: hencoder.com 
Content-Type: application/json; charset=utf-8 
Content-Length: 38 

{"name":"lvzishen","gender":"male"}
複製程式碼

響應中返回JSON:

HTTP/1.1 200 OK

content-type: application/json; charset=utf-8 
content-length: 234

[{"login":"mojombo","id":1,"node_id":"MDQ6VXNl cjE=","avatar_url":"https://avatars0.githubuse rcontent.com/u/1?v=4","gravat......
複製程式碼

image/jpeg:提交或獲取圖片

POST /user/1/avatar HTTP/1.1 

Host: hencoder.com 
Content-Type: image/jpeg 
Content-Length: 1575 

JFIFHH9......
複製程式碼

3.Content-Length

指定 Body 的長度(位元組)。用於二進位制檔案中的長度讀取,因為不能確定讀取到哪裡,所以規定長度,讀取到對應長度後代表讀取完成不再讀取。

4.Transfer: chunked (分塊傳輸編碼 Chunked Transfer Encoding)

用於當響應發起時,內容長度還沒能確定的情況下。和 Content-Length 不同時使用。用途是儘早給出響應,減少使用者等待。

HTTP/1.1 200 OK 

Content-Type: text/html 
Transfer-Encoding: chunked

4 
Chun                  <--不斷給出資料 先給4位元組的Chun,再給9位元組的ked Trans,.....,0代表傳輸完成全部載入完畢。
9 
ked Trans 
12 
fer Encoding 
0
複製程式碼

5.Location

指定重定向的目標的URL

6.User-Agent

使用者代理,即是誰實際傳送請求、接受響應的,例如手機瀏覽器、某款手機 App。

7.Range / Accept-Range

按範圍取資料

  • Accept-Range: bytes 響應報文中出現,表示伺服器支援按位元組來取範圍資料
  • Range: bytes =- 請求報文中出現,表示要取哪段資料
  • Content-Range:-/total 響應報文中出現,表示傳送的是哪段資料 作用:斷點續傳、多執行緒下載。

8.Cache

作用:在客戶端或中間網路節點快取資料,降低從伺服器取資料的頻率,以提高網路效能。

9.Cookie

HTTP全解析

HTTP全解析

  1. 伺服器需要客戶端儲存的內容,放在 Set-Cookie headers 裡返回,客戶端會自動儲存。
  2. 客戶端儲存的 Cookies,會在之後的所有請求中都攜帶進 Cookie header 裡發回給服務 器。
  3. 客戶端儲存 Cookie 是按照伺服器域名來分類的,例如 shop.com 發回的 Cookie 儲存下來 以後,在之後向 games.com 的請求中並不會攜帶。
  4. 客戶端儲存的 Cookie 在超時後會被刪除、沒有設定超時時間的 Cookie (稱作 Session Cookie)在瀏覽器關閉後就會自動刪除;另外,伺服器也可以主動刪除還未過期的客戶端 Cookies。

10.Authorization

(1)Basic

格式:Authorization: Basic username:password(Base64ed) 對使用者名稱密碼做Base64編碼,不是加密的,Base64只是編碼。 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

(2)Bearer

格式:Authorization: Bearer token bearer token 的獲取方式: 通過 OAuth2 的授權流程 OAuth2 的流程

HTTP全解析
0. 第三方網站向授權授權方網站申請第三方授權合作,拿到 client id 和 client secret

  1. 使用者在使用第三方網站時,點選「通過 XX (如 GitHub) 授權」按鈕,第三方網站將跳轉到授權網站,並傳入 client id 作為自己的身份標識
  2. 授權方網站根據 client id ,將第三方網站的資訊和第三方網站需要的使用者許可權展示給使用者,並詢問使用者是否同意授權
  3. 使用者點選「同意授權」按鈕後,授權方網站將跳轉回第三方網站,並傳入 Authorization code 作為使用者認可的憑證。
  4. 第三方網站將 Authorization code 傳送回自己的伺服器
  5. 伺服器將 Authorization code 和自己的 client secret 一併傳送給授權方的伺服器,授權方 伺服器在驗證通過後,返回 access token。OAuth 流程結束。
  6. 在上面的過程結束之後,第三方網站的伺服器(或者有時客戶端也會)就可以使用 access token 作為使用者授權的令牌,向授權方網站傳送請求來獲取使用者資訊或操作使用者賬戶。但這已經在 OAuth 流程之外。

為什麼 OAuth 要引入Authorization code,並需要申請授權的第三方將 Authorization code 傳送回自己的伺服器,再從伺服器來獲取 access token,而不是直接返回 access token ?這樣複雜的流程意義何在?

答:為了安全。OAuth 不強制授權流程必須使用 HTTPS,因此需要保證當通訊路徑中存在竊聽者時,依然具有足夠的安全性。


在自家 App 中使用 Bearer token 有的 App 會在 Api 的設計中,將登入和授權設計成類似 OAuth2 的過程,但簡化掉 Authorization code 概念。即:登入接收請求成功時,會返回 access token,然後客戶端在之 後的請求中,就可以使用這個 access token 來當做 bearer token 進行使用者操作了。 (這麼做失去了使用OAuth2的意義)

Refresh token 用法:access token 有失效時間,在它失效後,呼叫 refresh token 介面,傳入efresh_token 來獲取新的 access token。

{
"token_type": "Bearer", 
"access_token": "xxxxx", 
"refresh_token": "xxxxx", 
"expires_time": "xxxxx" 
}
複製程式碼

目的:安全。 當 access token 失竊時,由於它有失效時間,因此壞人只有較短的時間來「做壞事」;同時,由於(在標準的 OAuth2 流程中)refresh token 永遠只存在與第三方服務的服務 器中,因此 refresh token 幾乎沒有失竊的風險。 ##七.RESTful是什麼? 以HTTP標準協議去使用HTTP。 比如:

  1. 規範地使用method 來定義網路請求操作(刪除資料用DELETE請求,而不是用POST。獲取資料不要使用POST請求而應該使用GET請求)。
  2. 規範地使用 status code 來表示響應狀態。

八.HTTP1.0 HTTP 1.1主要區別

一.長連線 Keep-Alive

HTTP 1.0需要使用keep-alive引數來告知伺服器端要建立一個長連線,而HTTP1.1預設支援長連線。Connection:keep-alive(雖然是不斷開但是每次也只能序列的執行HTTP請求,2.0才支援並行) HTTP是基於TCP/IP協議的,建立一個TCP連線是需要經過三次握手的,有一定的開銷,如果每次通訊都要重新建立連線的話,對效能有影響。因此最好能維持一個長連線,可以用個長連線來發多個請求。 持久連線的時間引數,通常由伺服器設定,比如 nginx 的 keepalivetimeout,keepalive timout 時間值意味著:一個 http 產生的 tcp 連線在傳送完最後一個響應後,還需要 hold 住 keepalive_timeout (通常為5-15S)秒後,才開始關閉這個連線;

二.節約頻寬

HTTP 1.1支援只傳送header資訊(不帶任何body資訊),如果伺服器認為客戶端有許可權請求伺服器,則返回100,否則返回401。客戶端如果接受到100,才開始把請求body傳送到伺服器。 這樣當伺服器返回401的時候,客戶端就可以不用傳送請求body了,節約了頻寬。 另外HTTP還支援傳送內容的一部分。這樣當客戶端已經有一部分的資源後,只需要跟伺服器請求另外的部分資源即可。這是支援檔案斷點續傳的基礎。

三.HOST域

現在可以web server例如tomat,設定虛擬站點是非常常見的,也即是說,web server上的多個虛擬站點可以共享同一個ip和埠。 HTTP1.0是沒有host域的,HTTP1.1才支援這個引數。

九.HTTP1.1 HTTP 2.0主要區別

一.多路複用的單一長連結

1.單一長連線

在HTTP/2中,客戶端向某個域名的伺服器請求頁面的過程中,只會建立一條TCP連線,即使這頁面可能包含上百個資源。 單一的連線應該是HTTP2的主要優勢,單一的連線能減少TCP握手帶來的時延 。HTTP2中用一條單一的長連線,避免了建立多個TCP連線帶來的網路開銷,提高了吞吐量。

2.多路複用

HTTP2雖然只有一條TCP連線,但是在邏輯上分成了很多stream。 HTTP2把要傳輸的資訊分割成一個個二進位制幀,首部資訊會被封裝到HEADER Frame,相應的request body就放到DATA Frame,一個幀你可以看成路上的一輛車,只要給這些車編號,讓1號車都走1號門出,2號車都走2號門出,就把不同的http請求或者響應區分開來了。但是,這裡要求同一個請求或者響應的幀必須是有有序的,要保證FIFO的,但是不同的請求或者響應幀可以互相穿插。這就是HTTP2的多路複用,是不是充分利用了網路頻寬,是不是提高了併發度?

HTTP全解析

二.Header資料壓縮

HTTP1.1不支援header資料的壓縮,HTTP2.0使用HPACK演算法對header的資料進行壓縮,這樣資料體積小了,在網路上傳輸就會更快。 相當於建立一個對映表,如GET方法直接定義為對映表中的數字2,那麼GET請求時請求方法寫2就可以而不用寫GET,這樣就可以節省流量和空間。

三.伺服器推送

這個功能通常被稱作“快取推送”。主要的思想是:當一個客戶端請求資源X,而伺服器知道它很可能也需要資源Z的情況下,伺服器可以在客戶端傳送請求前,主動將資源Z推送給客戶端,這樣當使用Z資源時就不用請求網路直接本地取資料就可以了,加快獲取速度。

相關文章