這篇文章原本是我一年前看《圖解HTTP》作的筆記,但記完後放在文件夾的某個角落一直沒管。前段時間擼項目練手的時候,在狀態碼上碰到了問題,所以又拿了出來翻了翻,同時又在原有的基礎上作了些修改,補上了HTTPs的一些東西。這篇文章主要是對HTTP相對重要的知識的一些歸納,想要好好學習HTTP仍是須要看《圖解HTTP》或者《HTTP權威指南》,才能構建較爲完整的知識體系。最後,你沒有猜錯,我就是傳說中的標題黨,但但願這篇文章對你有用,哪怕是一丁點,2333。html
超文本傳輸協議(HTTP)是用於傳輸諸如HTML的超媒體文檔的應用層協議。它被設計用於Web瀏覽器和Web服務器之間的通訊,但它也能夠用於其餘目的。 HTTP遵循經典的客戶端-服務端模型,客戶端打開一個鏈接以發出請求,而後等待它收到服務器端響應。 HTTP是無狀態協議,意味着服務器不會在兩個請求之間保留任何數據(狀態)。雖然一般基於TCP / IP層,但能夠在任何可靠的傳輸層上使用.web
咱們常常會接觸到URL(統一資源定位符),它就是咱們用於訪問web的一個字符串地址.而URI對咱們來說就相對比較陌生了,它的名字叫作統一資源標識符(URI)。咱們來看看它們具體的區別吧:瀏覽器
(咱們平時所說的相對地址,其實只是相對於另外一個絕對地址而言的)安全
URL的基本格式以下:bash
schema://host[:port#]/path/.../[?query-string][#anchor]
複製代碼
格式 | 意義 |
---|---|
scheme | 指定低層使用的協議(例如:http, https, ftp)。 |
host | HTTP服務器的IP地址或者域名。 |
port# | HTTP服務器的默認端口是80,這種狀況下端口號能夠省略。若是使用了別的端口,必須指明。 |
path | 訪問資源的路徑。 |
query-string | 發送給http服務器的數據。 |
anchor- | 錨 |
HTTP的報文格式主要分爲報文首部和報文主體:服務器
其中的空行用於區分報文首部和報文主體內容,是由一個回車符和一個換行符組成的。cookie
不管是請求報文仍是響應報文都須要有報文首部,而報文主體有些請求報文是沒有的。而請求報文的通常格式以下:網絡
而響應報文的格式是這樣的:session
下面是谷歌瀏覽器的HTTP報文內容,其中request headers描述了請求報文頭部的內容,response headers描述了響應報文頭部的內容:併發
其中最多見的屬性以下:
接下來就聊一聊這些屬性的做用
發送HTTP的方式有不少,但最經常使用的仍是POST和GET。
GET:GET方法能夠用來請求訪問已經被URL識別的資源。指定的資源通過服務端解析後返回響應的內容。簡單來講,就是請求的資源是文本的話,那麼就保持原樣返回.
POST:POST方法能夠用來傳輸實體的主體。
這二者的區別主要以下:
POST與GET都用於獲取信息,可是GET方式僅僅是查詢,並不對服務器上的內容產生任何做用結果;每次GET的內容都是相同的。POST則經常使用於發送必定的內容進行某些修改操做。
因爲不一樣的瀏覽器對URL的長度大小有必定的字符限制,所以因爲GET方式放在URL的首部中,天然也跟着首先,可是具體的大小要依瀏覽器而定。POST方式則是把內容放在報文內容中,所以只要報文的內容沒有限制,它的大小就沒有限制。
上面也說了GET是直接添加到URL後面的,直接就能夠在URL中看到內容。而POST是放在報文內部的,用戶沒法直接看到。
總的來講,GET用於獲取某個內容,POST用於提交某種數據請求,從使用場景來看,通常用戶註冊的內容是私密的,應該使用POST方式來保持私密,而當須要查詢某個內容時,須要快速響應,則使用GET。
狀態碼一般就是服務器端對客戶端說的話,分類以下:
狀態碼 | 含義 |
---|---|
1** | 服務器收到請求,須要請求者繼續執行操做 |
2** | 成功,操做被成功接收並處理 |
3** | 從新定向,須要進一步的操做以完成請求 |
4** | 客戶端錯誤,請求包含語法錯誤或沒法完成請求 |
5** | 服務器錯誤,服務器在處理請求的過程當中發生了錯誤 |
常見的狀態碼:
GET:請求的對應資源會做爲響應返回。響應將包含描述或操做的結果。 POST:返回處理對應請求的結果。
表示服務器接收到的請求已經處理完畢,可是服務器不須要返回響應。好比,客戶端是瀏覽器的話,那麼瀏覽器顯示的頁面不會發生更新。
成功處理了部分GET請求
請求的網頁已永久移動到新位置,永久性重定向
網站臨時性重定向,暫時不能訪問(備案、被查)
該狀態碼錶示因爲請求對應的資源存在另外一個URI,並指定必須使用GET方法定向獲取請求的資源。和302不一樣的是,302是不會改變上次的請求方法
訪問不了,並返回和上次同樣的話,表示資源未被修改過,仍是和上次訪問時同樣。
臨時重定向,和30二、303相似,不一樣的是,不會指定客戶端要用什麼樣的方法請求,
表示客戶端中存在語法錯誤,致使服務器沒法理解該請求。客戶端須要修改請求的內容後再次發送請求。
即用戶沒有必要的憑據。該狀態碼錶示當前請求須要用戶驗證。
服務器已經理解請求,可是拒絕執行它。
服務器找不到請求的網頁。
服務器遇到錯誤,沒法完成請求。
因爲臨時的服務器維護或者過載,服務器當前沒法處理請求。這個情況是暫時的.
因爲有些報文的內容會過大,爲了減小傳輸時間,HTTP會採起一些壓縮的措施,例如上面的報文信息中,Accept-Encoding就定義了內容編碼的格式gzip。
總的來講內容編碼的格式有如下幾種:
正常發送HTTP時,咱們須要創建TCP的鏈接,而後再發送報文:
若是每次都要發送HTTP報文都須要經歷上面的拿過過程,無疑將會耗費不少時間在創建和斷開鏈接的過程當中,所以HTTP使用了connection屬性,用於指定鏈接的方式,噹噹設置成keep-alive時,就會創建一條持久化的鏈接。這樣就不須要每次都創建鏈接在中斷鏈接:
(HTTP1.1中connection默認開啓keep-alive)
因爲HTTP是一種無狀態的協議,這是因爲Web服務器要面對不少瀏覽器的併發訪問,爲了提升Web服務器對併發訪問的處理能力,在設計HTTP協議時規定Web服務器發送HTTP應答報文和文檔時,不保存發出請求的Web瀏覽器進程的任何狀態信息,從而減輕服務器端的負載,同時無狀態也減少了HTTP請求的開銷。
但當有些場景須要時刻記住用戶的信息時,無狀態很明顯不能知足需求,所以HTTP提供了cookie來解決這個問題,cookie技術經過在請求和相應報文中寫入cookie信息來控制客戶端的狀態。cookie會根據從服務端發送的相應報文內的一個叫作set-cookie的首部字段信息,通知客戶端保存cookie。當下次客戶端再往服務器發送請求的時候,客戶端會自動在請求頭加入cookie值後發送出去。在沒有cookie狀態下的請求:
當存有cookie後的請求:
簡單來講Cookie是一種由服務器端肯定,並保存在客戶端瀏覽器中的內容。這樣就與每次都去添加用戶的信息,請求會自動添加cookie中對應的內容。
(關於瀏覽器端的數據存儲感興趣的能夠看下這篇文章::聊一聊常見的瀏覽器端數據存儲方案)
在一些場景下,咱們在使用HTTP報文請求一些很大的圖片時,加載過程每每會很慢。(好比一些攝影網站)這時候咱們就會發現一些圖片是一塊一塊加載的。這是應爲設置了HTTP請求的長度,從而分塊的加載資源。在請求報文中使用Range屬性,在響應報文中使用Content-Type屬性均可以進行指定必定本身的HTTP請求。
(圖轉自:http://www.cnblogs.com/xing901022/p/4311987.html)
HTTP 支持幾種不一樣的請求命令,這些命令被稱爲 HTTP 方法(HTTP method)。每 條 HTTP 請求報文都包含一個方法。這個方法會告訴服務器要執行什麼動做(獲取 一個 Web 頁面、運行一個網關程序、刪除一個文件等)。下表是一些常見的HTTP方法:
HTTP方法 | 描述 |
---|---|
GET | 從服務器向客戶端發送命名資源 |
PUT | 未來自客戶端的數據存儲到一個命名的服務器資源中去 |
DELETE | 從服務器中刪除命名資源 |
POST | 將客戶端數據發送到一個服務器網關應用程序 |
HEAD | 僅發送命名資源響應中的 HTTP 首部 |
(GET和POST已在上面討論過了,這裏就不在討論了)
PUT方法用於傳輸文件,就像FTP協議的翁建上傳同樣,要求在請求報文的主題中包含文件內容,而後保存到請求URI指定的位置。因爲PUT方法不帶驗證機制,任何人均可以任何人均可以上傳文件,存在安全性問題,所以通常的web網站不適用該方法。
DELETE方法用來刪除文件,是與put相反的方法,DELETE方法按照請求url刪除指定的資源。其本質和PUT方法同樣不帶驗證機制,因此建議少用DELETE方法。
HEAD和GET方法同樣,只是不返回報文主體部分,一般用於確認url的有效性及資源更新的日期時間等。
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單來講就是是HTTP的安全版本,即在HTTP下加入SSL層,HTTPS的安全基石是SSL,所以加密的詳細內容就須要SSL。 它如今已經被普遍應用,好比GitHub,支付寶,掘金等。
這是因爲HTTP有這麼幾個缺點:
正是因爲以上這些缺點,HTTPS做出瞭如下一些改變:
能夠說HTTPS相對於HTTP就是套上了黃金甲的聖鬥士,變了身的奧特曼,沉睡了的毛利小五郎,不只僅提高了安全,還提高了逼格。但HTTPS也有一些缺陷:
有一些網站須要用戶的登陸從而獲取用戶的我的信息來進行接下來的操做,所以須要隨時知道這些消息,可是確定不能每次都讓用戶輸入用戶密碼,這樣會讓用戶感受很不爽,所以HTTP也自帶了認證的功能,認證方式主要以下:
其中BASIC認證是最簡單的認證,大體過程以下:
但它有如下缺陷:
正是因爲BASIC認證存在弱點,所以從HTTP/1.1起就有了DIGEST認證,DIGEST認證一樣使用質詢/響應的方式,但不會像BASIC認證那樣直接明文發送密碼。
SSL客戶端認證是藉由HTTPS的客戶端證書完成認證的方式。憑藉客戶端證書認證,服務器可確認訪問是否來自已登陸的客戶端。
SSL客戶端認證的步驟:
像支付寶,網銀之類對安全要求很高的網站,在登陸時,都須要下載一個數字認證,這個數字認證就屬於一種SSL客戶端的驗證。但它的缺點也很明顯,須要手動下載,對於如今愈來愈懶的網民們來說會感受很麻煩(包括我)
最後一種認證方式是最多見的,咱們能夠經過cookie或session來進行認證。
我前面提到過,HTTP是無狀態協議,沒法實現狀態管理,所以有了cookie。咱們就可使用Cookie來管理Session(會話),以彌補HTTP協議中不存在的狀態管理功能。
認證步驟:
參考資料: