HTTP全解析

一.Http是什麼?

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

二.Http請求格式

URL格式分爲三部分: 協議類型://服務器地址(和端口號)/路徑(Path) https://segmentfault.com/write?freshman=1node

三.Http的報文格式

1.請求:

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

2.響應:

  • 響應報文---->分爲:響應行,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狀態碼

用於對相應結果做出類型化描述。nginx

  • 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(元數據)。git

2.什麼是元數據? 通俗的講就是數據的屬性。以一個登陸接口爲例,用戶名密碼是上傳的數據(放在BODY中),那麼用戶名密碼的長度( Content-Length)、以什麼類型( Content-Type )上傳等等就是它的元數據。github

幾個重要的Header

1.Host

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

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中的內容)。 格式以下:json

POST /users HTTP/1.1

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

name=lvzishen&gender=male
複製代碼

對應 Retrofit 的代碼:segmentfault

@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中的內容)。 格式以下:api

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

  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 的流程

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的多路複用,是否是充分利用了網絡帶寬,是否是提升了併發度?

二.Header數據壓縮

HTTP1.1不支持header數據的壓縮,HTTP2.0使用HPACK算法對header的數據進行壓縮,這樣數據體積小了,在網絡上傳輸就會更快。 至關於創建一個映射表,如GET方法直接定義爲映射表中的數字2,那麼GET請求時請求方法寫2就能夠而不用寫GET,這樣就能夠節省流量和空間。

三.服務器推送

這個功能一般被稱做「緩存推送」。主要的思想是:當一個客戶端請求資源X,而服務器知道它極可能也須要資源Z的狀況下,服務器能夠在客戶端發送請求前,主動將資源Z推送給客戶端,這樣當使用Z資源時就不用請求網絡直接本地取數據就能夠了,加快獲取速度。

相關文章
相關標籤/搜索