1、什麼是Http
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從WWW服務器傳輸超文本到本地瀏覽器的傳送協議。它可以使瀏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正確快速地傳輸超文本文檔,還確定傳輸文檔中的哪一部分,以及哪部分內容首先顯示(如文本先於圖形)等。
HTTP是一個應用層協議,由請求和響應構成,是一個標準的客戶端服務器模型。HTTP是一個無狀態的協議。
2、 在TCP/IP協議棧中的位置
HTTP協議通常承載於TCP協議之上,有時也承載於TLS或SSL協議層之上,這個時候,就成了我們常說的HTTPS。如下圖所示:
默認HTTP的端口號爲80,HTTPS的端口號爲443。
3、HTTP的請求響應模型
HTTP協議永遠都是客戶端發起請求,服務器回送響應。見下圖:
這樣就限制了使用HTTP協議,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。HTTP協議是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關係。
4、工作流程
一次HTTP操作稱爲一個事務,其工作過程可分爲四步:
1)首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,HTTP的工作開始。
2)建立連接後,客戶機發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可能的內容。
3)服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。
4)客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然後客戶機與服務器斷開連接。
如果在以上過程中的某一步出現錯誤,那麼產生錯誤的信息將返回到客戶端,有顯示屏輸出。對於用戶來說,這些過程是由HTTP自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。
5、Http請求和響應包的結構一次請求就是向目標服務器發送一串文本。什麼樣的文本?有下面結構的文本。HTTP請求包結構:
請求包例子:
POST/meme.php/home/user/login HTTP/
1.1
Host:
114.215.86.90
Cache-Control: no-cache
Postman-Token: bd243d6b-da03-
902f-
0a2c-
8e9377f6f6ed
Content-Type:application/x-www-form-urlencoded
tel=
13637829200&password=
123456
請求了就會收到響應包(如果對面存在HTTP服務器),HTTP響應包結構:
響應包例子:
HTTP/
1.1
200 OK
Date: Sat,
02 Jan
2016
13:
20:
55 GMT
Server: Apache/
2.4.6 (CentOS) PHP/
5.6.14
X-Powered-By: PHP/
5.6.14
Content-Length:
78
Keep-Alive: timeout=
5, max=
100
Connection: Keep-Alive
Content-Type:application/json; charset=utf-
8
{
"status":
202,
"info":
"\u6b64\u7528\u6237\u4e0d\u5b58\u5728\uff01",
"data":null}
Http請求方式有:
方法 |
描述 |
GET |
請求指定url的數據,請求體爲空(例如打開網頁)。 |
POST |
請求指定url的數據,同時傳遞參數(在請求體中)。 |
HEAD |
類似於get請求,只不過返回的響應體爲空,用於獲取響應頭。 |
PUT |
從客戶端向服務器傳送的數據取代指定的文檔的內容。 |
DELETE |
請求服務器刪除指定的頁面。 |
CONNECT |
HTTP/1.1協議中預留給能夠將連接改爲管道方式的代理服務器。 |
OPTIONS |
允許客戶端查看服務器的性能。 |
TRACE |
回顯服務器收到的請求,主要用於測試或診斷。 |
常用只有Post與Get。
Get&Post
網絡請求中我們常用鍵值對來傳輸參數(少部分api用json來傳遞,畢竟不是主流)。通過上面的介紹,可以看出雖然Post與Get本意一個是表單提交一個是請求頁面,但本質並沒有什麼區別。下面說說參數在這2者的位置。
Get方式:
在url中填寫參數:
http:
//xxxx.xx.com/xx.php?params1=value1¶ms2=value2
甚至使用路由:
http:/
/xxxx.xx.com/xxx/value1/value2/value3
這些就是web服務器框架的事了。
Post方式
參數是經過編碼放在請求體中的。編碼包括x-www-form-urlencoded
與 form-data
。
x-www-form-urlencoded
的編碼方式是這樣:
tel=
13637829200&password=
123456
form-data
的編碼方式是這樣:
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data;name=
"tel"
13637829200
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data;name=
"password"
123456
----WebKitFormBoundary7MA4YWxkTrZu0gW
x-www-form-urlencoded
的優越性就很明顯了。不過x-www-form-urlencoded
只能傳鍵值對,但是form-data
可以傳二進制
因爲url是存在於請求行中的。所以Get與Post區別本質就是參數是放在請求行中還是放在請求體中。當然無論用哪種都能放在請求頭中。一般在請求頭中放一些發送端的常量。
有人說:
l Get是明文,Post隱藏
移動端不是瀏覽器,不用https全都是明文。
l Get傳遞數據上限XXX
胡說。有限制的是瀏覽器中的url長度,不是Http協議,移動端請求無影響。Http服務器部分有限制的設置一下即可。
l Get中文需要編碼
是真的...要注意。
URLEncoder.encode(params, "gbk");
還是建議用post規範參數傳遞方式。並沒有什麼更優秀,只是大家都這樣社會更和諧。
上面說的是請求。下面說響應。
請求是鍵值對,但返回數據我們常用Json。對於內存中的結構數據,肯定要用數據描述語言將對象序列化成文本,再用Http傳遞,接收端並從文本還原成結構數據。
對象(服務器)<-->文本(Http傳輸)<-->對象(移動端) 。
服務器返回的數據大部分都是複雜的結構數據,所以Json最適合。Json解析庫有很多Google的Gson,阿里的FastJson。