HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,在TCP/IP體系中屬於最高層(應用層)是用於從萬維網服務器傳輸超文本到本地瀏覽器的傳送協議。
HTTP協議工作於客戶端-服務端架構為上。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。Web服務器根據接收到的請求後,向客戶端發送響應信息。
這是最基本的HTTP工作原理,如圖所示:
C/S架構
HTTP報文
HTTP屬於應用層,應用層傳輸的數據單位是報文。
HTTP報文分為請求報文和響應報文。
請求報文
請求報文
HTTP請求報文由以下4個部分組成:
- 請求行:請求類型,要訪問的資源以及所使用的HTTP版本。
- 請求頭部:服務器要使用的附加信息。
- 空行:請求頭部後面的空行是必須的
- 請求包體:可以添加任意的其他數據
請求行
請求行組成:請求方法,請求URL,協議版本。
請求方法
請求URL
URL(Uniform Resource Locator)統一資源定位符,表示資源的地點(互聯網上的地址)。
URI(Uniform Resource Identifier)統一資源標識符,用字符串標識某一互聯網資源,URL是URI的子集。
協議版本
- HTTP/1.0:HTTP協議的第二個版本,第一個在通訊中指定版本號的HTTP協議版本,至今仍被廣泛採用
- HTTP/1.1:HTTP協議的第三個版本是HTTP 1.1,是目前使用最廣泛的協議版本
- HTTP/2.0:HTTP 2.0是下一代HTTP協議,目前應用還非常少
請求頭部
請求頭部由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。
有4種類型的首部字段:通用首部字段、請求首部字段、響應首部字段和實體首部字段,所有完整首部
這裡我們先了解下常用的請求首部。
請求包體
請求包體不在 GET 方法中使用,而是在POST 方法中使用。
HTTP請求的請求體有三種不同的形式:
- 任意類型:服務器不會解析請求體,請求體的處理需要自己解析,比如JSON
- 鍵值對(application/x-www-form-urlencoded):最常見的 POST 提交數據的方式,表單模式
- 文件分割:請求體被分成為多個部分,文件上傳時會被使用
示例
使用抓包工具或者Chrome來查看
<code>POST /getconfig HTTP/1.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Dalvik/2.1.0 (Linux; U; Android 9; Redmi Note 7 MIUI/V10.3.2.0.PFGCNXM)
Host: data.mistat.xiaomi.com
Accept-Encoding: gzip
Content-Length: 205
Connection: close
app_id=1000274&app_version=10.8.3/<code>
- 請求行:顯示Post請求,協議版本為HTTP/1.1
- 請求頭部:Content-Type,User-Agent,Host,Accept-Encoding,Content-Length,Connection
- 請求體:Content-Type聲明為鍵值對
響應報文
響應報文
HTTP 響應報文由狀態行、響應頭部、空行和響應包體4個部分組成。
狀態行
狀態行由HTTP協議版本字段、狀態碼和狀態碼的描述文本 3 個部分組成,他們之間使用空格隔開;
協議版本和請求中的對應,狀態碼和描述會一一對應。
狀態碼、描述
狀態碼由三位數字組成,第一位數字表示響應的類型,常用的狀態碼有五大類:
- 1xx:Informational(信息性狀態碼),接收的請求正在處理;
- 2xx:Success(成功狀態碼),請求正常處理完畢;
- 3xx:Redirection(重定向狀態碼),需要進行附加操作以完成請求;
- 4xx:Client Error(客戶端錯誤狀態碼),服務器無法處理請求;
- 5xx:Server Error(服務器錯誤狀態碼),服務器處理請求出錯;
常用的一些狀態碼和描述
1xx
狀態碼、描述說明100 Continue表明到目前為止都很正常,客戶端可以繼續發送請求或者忽略這個響應
2xx
狀態碼、描述說明200 OK請求成功204 No Content請求已經成功處理,但是返回的響應報文不包含實體的主體部分206 Partial Content表示客戶端進行了範圍請求,
響應報文包含由Content-Range指定範圍的實體內容
3xx
狀態碼、描述說明301 Moved Permanently永久性重定向302 Found臨時性重定向304 Not Modified如果請求報文首部包含一些條件,If-Match,If-Range,
If-Modified-Since,If-None-Match,,If-Unmodified-Since。
如果不滿足條件,則服務器會返回 304 狀態碼307 Temporary Redirect臨時重定向,與 302 的含義類似,
但是307要求瀏覽器不會把重定向請求的POST方法改成GET方法
4xx
狀態碼、描述說明400 Bad Request請求報文中存在語法錯誤401 Unauthorized請求需要驗證用戶403 Forbidden訪問權限問題404 Not Found
5xx
狀態碼、描述說明500 Internal Server Error服務器正在執行請求時發生錯誤503 Service Unavailable服務器正在執行請求時發生錯誤
響應頭部
和請求頭部一樣,由關鍵字/值對組成,每行一對,關鍵字和值用英文冒號“:”分隔。
常用的請求首部
字段說明Cache-Control控制緩存的行為Connection控制不再轉發給代理的首部字段、管理持久連接Transfer-Encoding指定報文主體的傳輸編碼方式Content-Encoding實體主體適用的編碼方式Content-Type實體主體的媒體類型Content-Length實體主體的大小Expires實體主體過期的日期時間ETag資源的匹配信息,和If-Nome-Match對應Date服務端創建報文的日期時間Location令客戶端重定向至指定 URIServerHTTP 服務器的安裝信息Last-Modified資源的最後修改日期時間Set-Cookie設置Cookie,客戶端得到響應報文後把 Cookie 內容保存到瀏覽器中
其他更詳細的首部信息,可以參考這裡
響應包體
服務器返回給客戶端的文本信息。
和請求包體的分類一樣。
示例
<code>HTTP/1.1 200 OK
Date: Sat, 13 Jul 2019 08:40:52 GMT
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Content-Encoding: gzip
Connection: close
{"errorCode":-2,"reason":"no changing","result":null}/<code>
- 響應行:返回響應碼200 Ok,表示服務端返回數據成功
- 響應頭部:Content-Type設置返回的類型為JSON格式
- 響應包體:返回具體JSON數據
HTTPS
HTTP 有以下安全性問題:
- 使用明文進行通信,內容可能會被竊聽;
- 不驗證通信方的身份,通信方的身份有可能遭遇偽裝;
- 無法證明報文的完整性,報文有可能遭篡改。
HTTPS 並不是新協議,而是讓 HTTP 先和 SSL(Secure Sockets Layer)通信,再由 SSL 和 TCP 通信,也就是說 HTTPS 使用了隧道進行通信。
通過使用 SSL,HTTPS 具有了加密(防竊聽)、認證(防偽裝)和完整性保護(防篡改)
HTTPS
與HTTP區別
協議原理數據格式傳輸速度端口HTTP應用層明文傳輸三次握手,傳輸三個包80HTTPS傳輸層SSL加密三次握手基礎上增加ssl握手(9個包),
傳輸12個包443
缺點
- 因為需要進行加密解密等過程,因此速度會更慢;
- 需要支付證書授權的高額費用。
HTTP框架
Volley
Volley是Google 官方出的一套小而巧的異步請求庫,該框架封裝的擴展性很強,支持 HttpClient、HttpUrlConnection,甚至支持OKHttp。
OKHttp
OKHttp是Square 公司開源的針對 Java 和 Android 程序,封裝的一個高性能 http 請求庫,所以它的職責跟 HttpUrlConnection 是一樣的,支持 spdy、http 2.0、websocket ,支持同步、異步。
已被谷歌加入到Android的源碼中。
Retrofit
Retrofit是Square公司出品的默認基於OKHttp 封裝的一套 RESTful 網絡請求框架
後續文章會從OKHttp、Retrofit角度來分析Http。
參考
- Http
- 這是一份全面& 詳細 HTTP協議 學習攻略
- 精讀《圖解HTTP》
- HTTP 協議入門
閱讀更多 Coder淘金 的文章