http全面解析,看這一篇就夠了!

1.什麼是http協議

HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網服務器傳輸超文本到本地瀏覽器的傳送協議。HTTP 是基於 TCP/IP 協議通訊協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。它不涉及數據包(packet)傳輸,主要規定了客戶端和服務器之間的通訊格式,默認使用80端口。css

什麼叫不涉及數據包的傳輸?
http協議是傳輸協議,屬於應用層協議,網絡四層模型中,傳輸層負責數據包的發送和網絡節點中數據包的流量控制傳輸等,能夠想象成http協議就是快遞的包裝盒,每個快遞實物都是一個應用程序,http負責應用程序之間數據包裝,快遞員至關於傳輸層的tcp協議等,來發送每個快遞。設計HTTP最初的目的是爲了提供一種發佈和接收HTML頁面的方法。經過HTTP或者HTTPS協議請求的資源由統一資源標識符(Uniform Resource Identifiers,URI)來標識。html

2.http協議有什麼特色

簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法經常使用的有GET、HEAD、PUT、DELETE、POST。每種方法規定了客戶與服務器聯繫的類型不一樣。因爲HTTP協議簡單,使得HTTP服務器的程序規模小,於是通訊速度很快。java

靈活:HTTP容許傳輸任意類型的數據對象。linux

無鏈接:無鏈接的含義是限制每次鏈接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開鏈接。採用這種方式能夠節省傳輸時間。android

無狀態:HTTP協議是無狀態的,HTTP 協議自身不對請求和響應之間的通訊狀態進行保存。任何兩次請求之間都沒有依賴關係。直觀地說,就是每一個請求都是獨立的,與前面的請求和後面的請求都是沒有直接聯繫的。協議自己並不保留以前一切的請求或 響應報文的信息。這是爲了更快地處理大量事務,確保協議的可伸縮性,而特地把 HTTP 協議設計成如此簡單的。git

3.Http報文格式

Http報文包括請求報文響應報文兩大部分
請求報文的組成:請求行(requestline)、請求頭(header)、空行和請求體四個部分組成;
響應報文的組成:狀態行、響應頭部、空行和響應體四個部分組成面試

3.1請求報文的格式

請求方法 URL HTTP/版本號
請求首部字段(可選)
空行
body(只對Post請求有效)
複製代碼

例如:ajax

GET http://m.baidu.com/ HTTP/1.1
Host m.baidu.com
Connection Keep-Alive
...// 其餘header

key=android
複製代碼

上面的例子能夠很容易看出,請求行包括三個部分
請求方法、url、http版本號;算法

看到這裏不要慌,怎麼像俄羅斯套娃,這麼多包括,太難了!跨域

3.1.1請求方法

請求方法包括(又來了,包括沒辦法呀)請求方法常規有八種類型:

序號 方法 描述
1 GET 發送請求來得到服務器上的資源,請求體中不會包含請求數據,請求數據放在協議頭中。另外get支持快取、緩存、可保留書籤等。冪等
2 POST 和get同樣很常見,向服務器提交資源讓服務器處理,好比提交表單、上傳文件等,可能致使創建新的資源或者對原有資源的修改。提交的資源放在請求體中。不支持快取。非冪等
3 HEAD 本質和get同樣,可是響應中沒有呈現數據,而是http的頭信息,主要用來檢查資源或超連接的有效性或是否能夠可達、檢查網頁是否被串改或更新,獲取頭信息等,特別適用在有限的速度和帶寬下。
4 PUT 和post相似,html表單不支持,發送資源與服務器,並存儲在服務器指定位置,要求客戶端事先知道該位置;好比post是在一個集合上(/province),而put是具體某一個資源上(/province/123)。因此put是安全的,不管請求多少次,都是在123上更改,而post可能請求幾回建立了幾回資源。冪等
5 DELETE 請求服務器刪除某資源。和put都具備破壞性,可能被防火牆攔截。若是是https協議,則無需擔憂。冪等
6 CONNECT HTTP/1.1協議中預留給可以將鏈接改成管道方式的代理服務器。就是把服務器做爲跳板,去訪問其餘網頁而後把數據返回回來,鏈接成功後,就能夠正常的get、post了。
7 OPTIONS 獲取http服務器支持的http請求方法,容許客戶端查看服務器的性能,好比ajax跨域時的預檢等。
8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。通常禁用,防止被惡意攻擊或盜取信息。

這八種方法其中
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT

這裏有個關鍵字冪等性,what 啥意思呀?
冪等的概念是指同一個請求方法執行屢次和僅執行一次的效果徹底相同,

3.1.2 請求url

這個好像沒什麼好說的,就是通常的url鏈接,例如http://m.baidu.com/ 仍是說點吧!
使用HTTP協議訪問資源是經過URL(Uniform Resource Locator)統一資源定位符來實現的。URL的格式以下

scheme://host:port/path?query

scheme: 表示協議,如Http, Https, Ftp等;
host: 表示所訪問資源所在的主機名:如:www.baidu.com;
port: 表示端口號,默認爲80;
path: 表示所訪問的資源在目標主機上的儲存路徑;
query: 表示查詢條件;

例如: http://www.baidu.com/search?words=Baidu

複製代碼
3.1.3 http版本

http有好多版本

  • HTTP/0.9 HTTP協議的最第一版本,功能簡陋,僅支持請求方式GET,而且僅能請求訪問HTML格式的資源。 沒有首部;只能獲取純文本,請求完成後即關閉TCP鏈接
  • HTTP/1.0
    • 任何格式的內容均可以發送。不只能夠傳輸文字,還能傳輸圖像、視頻、二進制文件。
    • 除了GET命令,還引入了POST命令和HEAD命令,豐富了瀏覽器與服務器的互動手段。
    • HTTP請求和迴應的格式也變了。除了數據部分,每次通訊都必須包括頭信息(HTTP header),用來描述一些元數據。
    • 新增功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)等
  • HTTP1.1
    • 持久鏈接(keep-alive):TCP鏈接默認不關閉,能夠被多個請求複用
    • 管道機制(pipelining):同一個TCP鏈接裏面,客戶端能夠同時發送多個請求。可是服務器仍是按照順序響應。
    • 分塊傳輸編碼:對於動態生成的響應類容,可使用分塊傳輸,邊生成邊發送
    • 新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。
    • 客戶端請求的頭信息新增了Host字段,用來指定服務器的域名:有了Host字段,就能夠將請求發往同一臺服務器上的不一樣網站,爲虛擬主機的興起打下了基礎。
  • HTTP2.0
    • 多路複用:HTTP2創建一個TCP鏈接,一個鏈接上面能夠有任意多個流(stream),消息分割成一個或多個幀在每一個流裏面傳輸。幀傳輸過去之後,再進行重組,造成一個完整的請求或響應。
    • 二進制幀:1.1響應是文本格式,而2.0把響應劃分紅了兩個幀,HEADERS和DATA 是幀的類型。也就是說一條HTTP響應,劃分紅了兩個幀來傳輸,而且採用二進制來編碼。
    • 頭信息壓縮:每一個請求帶的一些首部字段都是相同的,例如cookie、user-agent等。HTTP2壓縮首部。
    • 服務器推送:服務器端推送使得服務器能夠預測客戶端須要的資源,主動推送到客戶端。如客戶端請求index.html,服務器端可以額外推送script.js和style.css。

3.2 首部字段

這個地方字段太多!

HTTP首部字段由字段名和字段值組成,中間以":"分隔,如Content-Type: text/html.其中,同一個字段名可對應多個字段值。

HTTP的報文字段分爲5種:

  • 請求報文字段
  • 應答報文字段
  • 實體首部字段
  • 通用報文字段
  • 其餘報文字段
3.2.1 請求報文字段
Accept:客戶端可以處理的媒體類型。如text/html, 表示客戶端讓服務器返回html類型的數據,若是沒有,返回text
類型的也能夠。媒體類型的格式通常爲:type/subType, 表示優先請求subType類型的數據,若是沒有,返回type類型
數據也能夠。

常見的媒體類型:
文本文件:text/html, text/plain, text/css, application/xml
圖片文件:iamge/jpeg, image/gif, image/png;
視頻文件:video/mpeg
應用程序使用的二進制文件:application/octet-stream, application/zip

Accept字段可設置多個字段值,這樣服務器依次進行匹配,並返回最早匹配到的媒體類型,固然,也可經過q參數來設置
媒體類型的權重,權重越高,優先級越高。q的取值爲[0, 1], 可取小數點後3位,默認爲1.0。例如:
Accept: text/html, application/xml; q=0.9, */*

Accept-Charset: 表示客戶端支持的字符集。例如:Accept-Charset: GB2312, ISO-8859-1

Accept-Encoding: 表示客戶端支持的內容編碼格式。如:Accept-Encoding:gzip

經常使用的內容編碼:
gzip: 由文件壓縮程序gzip生成的編碼格式;
compress: 由Unix文件壓縮程序compress生成的編碼格式;
deflate: 組合使用zlib和deflate壓縮算法生成的編碼格式;
identity:默認的編碼格式,不執行壓縮。

Accept-Language:表示客戶端支持的語言。如:Accept-Language: zh-cn, en

Authorization:表示客戶端的認證信息。客戶端在訪問須要認證的也是時,服務器會返回401,隨後客戶端將認證信息
加在Authorization字段中發送到服務器後,若是認證成功,則返回200. 如Linux公社下的Ftp服務器就是這種流程:
ftp://ftp1.linuxidc.com。

Host: 表示訪問資源所在的主機名,即URL中的域名部分。如:m.baidu.com

If-Match: If-Match的值與所請求資源的ETag值(實體標記,與資源相關聯。資源變化,實體標記跟着變化)一致時,
服務器才處理此請求。

If-Modified-Since: 用於確認客戶端擁有的本地資源的時效性。 若是客戶端請求的資源在If-Modified-Since指定
的時間後發生了改變,則服務器處理該請求。如:If-Modified-Since:Thu 09 Jul 2018 00:00:00, 表示若是客戶
端請求的資源在2018年1月9號0點以後發生了變化,則服務器處理改請求。經過該字段咱們可解決如下問題:有一個包含大
量數據的接口,且實時性較高,咱們在刷新時就可以使用改字段,從而避免多餘的流量消耗。

If-None-Match: If-Match的值與所請求資源的ETag值不一致時服務器才處理此請求。

If-Range: If-Range的值(ETag值或時間)與所訪問資源的ETag值或時間相一致時,服務器處理此請求,並返回
Range字段中設置的指定範圍的數據。若是不一致,則返回全部內容。If-Range其實算是If-Match的升級版,由於它
的值不匹配時,依然可以返回數據,而If-Match不匹配時,請求不會被處理,須要數據時需再次進行請求。


If-Unmodified-Since:與If-Modified-Since相反,表示請求的資源在指定的時間以後未發生變化時,才處理請求,
不然返回412。

Max-Forwards:表示請求可通過的服務器的最大數目,請求每被轉發一次,Max-Forwards減1,當Max-Forwards爲0
時,所在的服務器將再也不轉發,而是直接作出應答。經過此字段可定位通訊問題,好比以前支付寶光纖被挖斷,就可經過設
置Max-Forwards來定位大概的位置。

Proxy-Authorization:當客戶端接收到來自代理服務器的認證質詢時,客戶端會將認證信息添加到
Proxy-Authorization來完成認證。與Authorization相似,只不過Authorization是發生在客戶端與服務端之間。

Range:獲取部分資源,例如:Range: bytes=500-1000表示獲取指定資源的第500到1000字節之間的內容,若是服務器
可以正確處理,則返回206做爲應答,表示返回了部分數據,若是不能處理這種範圍請求,則以200做爲應答,返回完整的
數據,

Referer:告知服務器請求是從哪一個頁面發起的。例如在百度首頁中搜索某個關鍵字,結果頁面的請求頭部就會有這個字段,
其值爲https://www.baidu.com/。經過這個字段可統計廣告的點擊狀況。

User-Agent:將發起請求的瀏覽器和代理名稱等信息發送給服務端,例如:
User-Agent: Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/63.0.3239.84 Mobile Safari/537.36

複製代碼
3.2.2 應答報文字段
Age:服務端告知客戶端,源服務器(而不是緩存服務器)在多久以前建立了響應。
單位爲秒。

ETag: 實體資源的標識,可用來請求指定的資源。

Location:請求的資源所在的新位置。

Proxy-Authenticate:將代理服務器須要的認證信息發送給客戶端。

Retry-After:服務端告知客戶端多久以後再重試,通常與503和3xx重定向類型的應答一塊兒使用。

Server:告知服務端當前使用的HTTP服務器應用程序的相關信息。

WWW-Authenticate:告知客戶端適用於所訪問資源的認證方案,如Basic或Digest。401的響應中確定帶有
WWW-Authenticate字段。
複製代碼
3.2.3 實體首部字段
Allow:通知客戶端,服務器所支持的請求方法。但服務器收到不支持的請求方法時,會以405(Method Not Allowed)
做爲響應。
    
Content-Encoding:告知客戶端,服務器對資源的內容編碼。
  
Content-Language:告知客戶端,資源所使用的天然語言。
  
Content-Length:告知客戶端資源的長度
  
Content-Location:告知客戶端資源所在的位置。
  
Content-Type:告知客戶端資源的媒體類型,取值同請求首部字段中的Accept。
  
Expires:告知客戶端資源的失效日期。可用於對緩存的處理。
  
Last-Modified:告知客戶端資源最後一次修改的時間。

複製代碼
3.2.4 通用報文字段

可在HTTP請求中使用,也可在HTTP應答中使用的報文字段。

Cache-Control:控制緩存行爲;

Connection:管理持久鏈接,設置其值爲Keep-Alive可實現長鏈接。

Date:建立HTTP報文的日期和時間。

Pragma:Http/1.1以前的歷史遺留字段,僅做爲HTTP/1.0向後兼容而定義,雖然是通用字段,當一般被使用在客戶單的
請求中,如Pragma: no-cache, 表示客戶端在請求過程當中不循序服務端返回緩存的數據;

Transfer-Encoding:規定了傳輸報文主題時使用的傳輸編碼,如Transfer-Encoding: chunked

Upgrade: 用於檢查HTTP協議或其餘協議是否有可以使用的更高版本。

Via:追蹤客戶端和服務端之間的報文的傳輸路徑,還可避免會環的發生,因此在通過代理時必須添加此字段。

Warning:Http/1.1的報文字段,從Http/1.0的AfterRetry演變而來,用來告知用戶一些與緩存相關的警告信息。

複製代碼
3.2.5 其餘報文字段

這些字段不是HTTP協議中定義的,但被普遍應用於HTTP請求中。
Cookie:屬於請求型報文字段,在請求時添加Cookie, 以實現HTTP的狀態記錄。
Set-Cookie:屬於應答型報文字段。服務器給客戶端傳遞Cookie信息時,就是經過此字段實現的。

Set-Cookie的字段屬性:

NAME=VALUE:賦予Cookie的名稱和值;
expires=DATE: Cookie的有效期;
path=PATH: 將服務器上的目錄做爲Cookie的適用對象,若不指定,則默認爲文檔所在的文件目錄;
domin=域名:做爲Cookies適用對象的域名,若不指定,則默認爲建立Cookie的服務器域名;
Secure: 僅在HTTPS安全通訊是纔會發送Cookie;
HttpOnly: 使Cookie不能被JS腳本訪問;

如:Set-Cookie:BDSVRBFE=Go; max-age=10; domain=m.baidu.com; path=/

複製代碼

3.3 響應報文的格式

HTTP/版本號 返回碼 返回碼描述
應答首部字段(可選)
空行
body

複製代碼

例以下面的內容

HTTP/1.1 200 OK
Content-Type text/html;charset=UTF-8
...// 其餘header

<html>...

複製代碼

http響應報文跟請求報文大部份內容類似;http版本號,上面已經介紹了!

返回碼,有的時候也叫狀態碼

下面是常見的HTTP狀態碼:

200 - 請求成功
301 - 資源(網頁等)被永久轉移到其它URL
404 - 請求的資源(網頁等)不存在
500 - 內部服務器錯誤
複製代碼

http狀態碼的分類

HTTP狀態碼由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型,後兩個數字沒有分類的做用。HTTP狀態碼共分爲5種類型:

HTTP狀態碼分類 分類描述
1** 信息,服務器收到請求,須要請求者繼續執行操做
2** 成功,操做被成功接收並處理
3** 重定向,須要進一步的操做以完成請求
4** 客戶端錯誤,請求包含語法錯誤或沒法完成請求
5** 服務器錯誤,服務器在處理請求的過程當中發生了錯誤

http狀態碼列表

狀態碼 狀態碼英文名稱 中文描述
100 Continue 繼續。客戶端應繼續其請求
101 Switching Protocols 切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協議,例如,切換到HTTP的新版本協議
200 OK 請求成功。通常用於GET與POST請求
201 Created 已建立。成功請求並建立了新的資源
202 Accepted 已接受。已經接受請求,但未處理完成
203 Non-Authoritative Information 非受權信息。請求成功。但返回的meta信息不在原始的服務器,而是一個副本
204 No Content 無內容。服務器成功處理,但未返回內容。在未更新網頁的狀況下,可確保瀏覽器繼續顯示當前文檔
205 Reset Content 重置內容。服務器處理成功,用戶終端(例如:瀏覽器)應重置文檔視圖。可經過此返回碼清除瀏覽器的表單域
206 Partial Content 部份內容。服務器成功處理了部分GET請求
300 Multiple Choices 多種選擇。請求的資源可包括多個位置,相應可返回一個資源特徵與地址的列表用於用戶終端(例如:瀏覽器)選擇
301 Moved Permanently 永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。從此任何新的請求都應使用新的URI代替
302 Found 臨時移動。與301相似。但資源只是臨時被移動。客戶端應繼續使用原有URI
303 See Other 查看其它地址。與301相似。使用GET和POST請求查看
304 Not Modified 未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。客戶端一般會緩存訪問過的資源,經過提供一個頭信息指出客戶端但願只返回在指定日期以後修改的資源
305 Use Proxy 使用代理。所請求的資源必須經過代理訪問
306 Unused 已經被廢棄的HTTP狀態碼
307 Temporary Redirect 臨時重定向。與302相似。使用GET請求重定向
400 Bad Request 客戶端請求的語法錯誤,服務器沒法理解
401 Unauthorized 請求要求用戶的身份認證
402 Payment Required 保留,未來使用
403 Forbidden 服務器理解請求客戶端的請求,可是拒絕執行此請求
404 Not Found 服務器沒法根據客戶端的請求找到資源(網頁)。經過此代碼,網站設計人員可設置"您所請求的資源沒法找到"的個性頁面
405 Method Not Allowed 客戶端請求中的方法被禁止
406 Not Acceptable 服務器沒法根據客戶端請求的內容特性完成請求
407 Proxy Authentication Required 請求要求代理的身份認證,與401相似,但請求者應當使用代理進行受權
408 Request Time-out 服務器等待客戶端發送的請求時間過長,超時
409 Conflict 服務器完成客戶端的 PUT 請求時可能返回此代碼,服務器處理請求時發生了衝突
410 Gone 客戶端請求的資源已經不存在。410不一樣於404,若是資源之前有如今被永久刪除了可以使用410代碼,網站設計人員可經過301代碼指定資源的新位置
411 Length Required 服務器沒法處理客戶端發送的不帶Content-Length的請求信息
412 Precondition Failed 客戶端請求信息的先決條件錯誤
413 Request Entity Too Large 因爲請求的實體過大,服務器沒法處理,所以拒絕請求。爲防止客戶端的連續請求,服務器可能會關閉鏈接。若是隻是服務器暫時沒法處理,則會包含一個Retry-After的響應信息
414 Request-URI Too Large 請求的URI過長(URI一般爲網址),服務器沒法處理
415 Unsupported Media Type 服務器沒法處理請求附帶的媒體格式
416 Requested range not satisfiable 客戶端請求的範圍無效
417 Expectation Failed 服務器沒法知足Expect的請求頭信息
500 Internal Server Error 服務器內部錯誤,沒法完成請求
501 Not Implemented 服務器不支持請求的功能,沒法完成請求
502 Bad Gateway 做爲網關或者代理工做的服務器嘗試執行請求時,從遠程服務器接收到了一個無效的響應
503 Service Unavailable 因爲超載或系統維護,服務器暫時的沒法處理客戶端的請求。延時的長度可包含在服務器的Retry-After頭信息中
504 Gateway Time-out 充當網關或代理的服務器,未及時從遠端服務器獲取請求
505 HTTP Version not supported 服務器不支持請求的HTTP協議的版本,沒法完成處理

http基礎的知識基本就這些了!這個狀態碼太多了,什麼你全記住了,牛!

4.http的一些問題

4.1 HTTP的keep-alive是幹什麼的?

在早期的HTTP/1.0中,每次http請求都要建立一個鏈接,而建立鏈接的過程須要消耗資源和時間,爲了減小資源消耗,縮短響應時間,就須要重用鏈接。在後來的HTTP/1.0中以及HTTP/1.1中,引入了重用鏈接的機制,就是在http請求頭中加入Connection: keep-alive來告訴對方這個請求響應完成後不要關閉,下一次我們還用這個請求繼續交流。協議規定HTTP/1.0若是想要保持長鏈接,須要在請求頭中加上Connection: keep-alive。 keep-alive的優勢:

  • 較少的CPU和內存的使用(因爲同時打開的鏈接的減小了)
  • 容許請求和應答的HTTP管線化
  • 下降擁塞控制 (TCP鏈接減小了)
  • 減小了後續請求的延遲(無需再進行握手)
  • 報告錯誤無需關閉TCP連

4.2 GET和POST有什麼區別?

  • 數據傳輸方式不一樣:GET請求經過URL傳輸數據,而POST的數據經過請求體傳輸。
  • 安全性不一樣:POST的數據由於在請求主體內,因此有必定的安全性保證,而GET的數據在URL中,經過歷史記錄,緩存很容易查到數據信息。
  • 數據類型不一樣:GET只容許 ASCII 字符,而POST無限制
  • GET無害: 刷新、後退等瀏覽器操做GET請求是無害的,POST可能重複提交表單
  • 特性不一樣:GET是安全(這裏的安全是指只讀特性,就是使用這個方法不會引發服務器狀態變化)且冪等(冪等的概念是指同一個請求方法執行屢次和僅執行一次的效果徹底相同),而POST是非安全非冪等

這個問題面試中可能常常會問到,多少說點意思意思呀!

4.3 http不保存狀態和cookie是什麼?

HTTP 協議對於發送的請求和響應不作持久化處理。這時候引入了 Cookie 技術用於狀態管理。Cookie 對用與登陸的狀態管理,沒有 Cookie 這個技術的話,由於 HTTP 不保存狀態,每次打開新網頁都必須再次登陸。 Cookie 會根據響應報文中的 Set-Cookie 字段來通知客戶端自動保存 Cookie。下次請求時會自動發送 Cookie,服務器會比對數據獲得狀態結果。

往期文章推薦
那些年你曾經工做過的奇葩公司能有多奇葩!
Kotlin擴展和對應的java代碼解析
git操做高級命令
瞭解一下計算機網絡層吧
計算機網絡基礎
帶你深刻了解運輸層
看看網絡安全的一些知識吧!
是時候瞭解一下應用層的知識了一塊兒來吧!
如何使用命令行卸載手機預知APP

長按二維碼關注公衆號,接收新的消息推送,值得期待喲!更有奇葩公司的後續傳奇經歷,等待與您分享,感謝您的支持!

技術乾貨店
相關文章
相關標籤/搜索