那些前端應該知道的HTTP知識

前言

這篇文章原本是我一年前看《圖解HTTP》作的筆記,但記完後放在文件夾的某個角落一直沒管。前段時間擼項目練手的時候,在狀態碼上碰到了問題,所以又拿了出來翻了翻,同時又在原有的基礎上作了些修改,補上了HTTPs的一些東西。這篇文章主要是對HTTP相對重要的知識的一些歸納,想要好好學習HTTP仍是須要看《圖解HTTP》或者《HTTP權威指南》,才能構建較爲完整的知識體系。最後,你沒有猜錯,我就是傳說中的標題黨,但但願這篇文章對你有用,哪怕是一丁點,2333。html

1.HTTP簡述(出自MDN)

超文本傳輸協議(HTTP)是用於傳輸諸如HTML的超媒體文檔的應用層協議。它被設計用於Web瀏覽器和Web服務器之間的通訊,但它也能夠用於其餘目的。 HTTP遵循經典的客戶端-服務端模型,客戶端打開一個鏈接以發出請求,而後等待它收到服務器端響應。 HTTP是無狀態協議,意味着服務器不會在兩個請求之間保留任何數據(狀態)。雖然一般基於TCP / IP層,但能夠在任何可靠的傳輸層上使用.web

2.URL和URI

咱們常常會接觸到URL(統一資源定位符),它就是咱們用於訪問web的一個字符串地址.而URI對咱們來說就相對比較陌生了,它的名字叫作統一資源標識符(URI)。咱們來看看它們具體的區別吧:瀏覽器

  • URI:uniform resource identifier 統一資源標識符,一種資源的標識,它是一種抽象的資源標識,便可以是相對的,也能夠是絕對的。
  • URL:uniform resource location 統一資源定位符,同時一種資源的標識,但指明瞭如何定位Locate這個資源。由於它指明瞭定位的信息,因此必須是絕對的。

(咱們平時所說的相對地址,其實只是相對於另外一個絕對地址而言的)安全

2.1 URL

URL的基本格式以下:bash

schema://host[:port#]/path/.../[?query-string][#anchor]
複製代碼
格式 意義
scheme 指定低層使用的協議(例如:http, https, ftp)。
host HTTP服務器的IP地址或者域名。
port# HTTP服務器的默認端口是80,這種狀況下端口號能夠省略。若是使用了別的端口,必須指明。
path 訪問資源的路徑。
query-string 發送給http服務器的數據。
anchor-

3.HTTP報文

3.1 HTTP報文格式

HTTP的報文格式主要分爲報文首部和報文主體:服務器

image

其中的空行用於區分報文首部和報文主體內容,是由一個回車符和一個換行符組成的。cookie

不管是請求報文仍是響應報文都須要有報文首部,而報文主體有些請求報文是沒有的。而請求報文的通常格式以下:網絡

image

而響應報文的格式是這樣的:session

image

下面是谷歌瀏覽器的HTTP報文內容,其中request headers描述了請求報文頭部的內容,response headers描述了響應報文頭部的內容:併發

image

其中最多見的屬性以下:

  1. URL, 即http訪問的地址
  2. request method, 報文的請求方式
  3. status code, 狀態碼以及狀態短語
  4. Accept Encoding, 內容編碼
  5. Connection, 鏈接方式
  6. Cookie, 添加的cookie內容
  7. Host, 目標主機
  8. User-Agent, 客戶端瀏覽器的相關信息
  9. Set-Cookie, 指定想要在Cookie中保存的內容

接下來就聊一聊這些屬性的做用

3.2 HTTP請求方式(request method)——GET and POST

發送HTTP的方式有不少,但最經常使用的仍是POST和GET。

  • GET:GET方法能夠用來請求訪問已經被URL識別的資源。指定的資源通過服務端解析後返回響應的內容。簡單來講,就是請求的資源是文本的話,那麼就保持原樣返回.

    image

  • POST:POST方法能夠用來傳輸實體的主體。

image

這二者的區別主要以下:

  1. 使用目標不一樣

POST與GET都用於獲取信息,可是GET方式僅僅是查詢,並不對服務器上的內容產生任何做用結果;每次GET的內容都是相同的。POST則經常使用於發送必定的內容進行某些修改操做。

  1. 大小不一樣

因爲不一樣的瀏覽器對URL的長度大小有必定的字符限制,所以因爲GET方式放在URL的首部中,天然也跟着首先,可是具體的大小要依瀏覽器而定。POST方式則是把內容放在報文內容中,所以只要報文的內容沒有限制,它的大小就沒有限制。

  1. 安全性不一樣

上面也說了GET是直接添加到URL後面的,直接就能夠在URL中看到內容。而POST是放在報文內部的,用戶沒法直接看到。

總的來講,GET用於獲取某個內容,POST用於提交某種數據請求,從使用場景來看,通常用戶註冊的內容是私密的,應該使用POST方式來保持私密,而當須要查詢某個內容時,須要快速響應,則使用GET。

3.3 status code狀態碼

狀態碼一般就是服務器端對客戶端說的話,分類以下:

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

常見的狀態碼:

  • 200 一般的成功 OK

GET:請求的對應資源會做爲響應返回。響應將包含描述或操做的結果。 POST:返回處理對應請求的結果。

  • 204 成功處理請求,沒有返回任何內容 No Content

表示服務器接收到的請求已經處理完畢,可是服務器不須要返回響應。好比,客戶端是瀏覽器的話,那麼瀏覽器顯示的頁面不會發生更新。

  • 206 Partial Content

成功處理了部分GET請求

  • 301 Moved Permanently

請求的網頁已永久移動到新位置,永久性重定向

  • 302 Found

網站臨時性重定向,暫時不能訪問(備案、被查)

  • 303 See Other

該狀態碼錶示因爲請求對應的資源存在另外一個URI,並指定必須使用GET方法定向獲取請求的資源。和302不一樣的是,302是不會改變上次的請求方法

  • 304 Not Modified

訪問不了,並返回和上次同樣的話,表示資源未被修改過,仍是和上次訪問時同樣。

  • 307 Temporary Redirect

臨時重定向,和30二、303相似,不一樣的是,不會指定客戶端要用什麼樣的方法請求,

  • 400 Bad Request

表示客戶端中存在語法錯誤,致使服務器沒法理解該請求。客戶端須要修改請求的內容後再次發送請求。

  • 401 Unauthorized

即用戶沒有必要的憑據。該狀態碼錶示當前請求須要用戶驗證。

  • 403 Forbidden

服務器已經理解請求,可是拒絕執行它。

  • 404 Not Found

服務器找不到請求的網頁。

  • 500 Internal Server Error

服務器遇到錯誤,沒法完成請求。

  • 503 Service Unavailable

因爲臨時的服務器維護或者過載,服務器當前沒法處理請求。這個情況是暫時的.

3.4 內容編碼 Accept Encoding

因爲有些報文的內容會過大,爲了減小傳輸時間,HTTP會採起一些壓縮的措施,例如上面的報文信息中,Accept-Encoding就定義了內容編碼的格式gzip。

總的來講內容編碼的格式有如下幾種:

  • gzip:GNU壓縮格式
  • compress:UNIX系統的標準壓縮格式
  • deflate:是一種同時使用了LZ77和哈夫曼編碼的無損失壓縮格式
  • identity:不進行壓縮

3.5 持久化——connection

正常發送HTTP時,咱們須要創建TCP的鏈接,而後再發送報文:

image

若是每次都要發送HTTP報文都須要經歷上面的拿過過程,無疑將會耗費不少時間在創建和斷開鏈接的過程當中,所以HTTP使用了connection屬性,用於指定鏈接的方式,噹噹設置成keep-alive時,就會創建一條持久化的鏈接。這樣就不須要每次都創建鏈接在中斷鏈接:

image

(HTTP1.1中connection默認開啓keep-alive)

3.6 無狀態的HTTP——cookie

因爲HTTP是一種無狀態的協議,這是因爲Web服務器要面對不少瀏覽器的併發訪問,爲了提升Web服務器對併發訪問的處理能力,在設計HTTP協議時規定Web服務器發送HTTP應答報文和文檔時,不保存發出請求的Web瀏覽器進程的任何狀態信息,從而減輕服務器端的負載,同時無狀態也減少了HTTP請求的開銷。

但當有些場景須要時刻記住用戶的信息時,無狀態很明顯不能知足需求,所以HTTP提供了cookie來解決這個問題,cookie技術經過在請求和相應報文中寫入cookie信息來控制客戶端的狀態。cookie會根據從服務端發送的相應報文內的一個叫作set-cookie的首部字段信息,通知客戶端保存cookie。當下次客戶端再往服務器發送請求的時候,客戶端會自動在請求頭加入cookie值後發送出去。在沒有cookie狀態下的請求:

image

當存有cookie後的請求:

image

簡單來講Cookie是一種由服務器端肯定,並保存在客戶端瀏覽器中的內容。這樣就與每次都去添加用戶的信息,請求會自動添加cookie中對應的內容。

(關於瀏覽器端的數據存儲感興趣的能夠看下這篇文章::聊一聊常見的瀏覽器端數據存儲方案

3.7 範圍請求

在一些場景下,咱們在使用HTTP報文請求一些很大的圖片時,加載過程每每會很慢。(好比一些攝影網站)這時候咱們就會發現一些圖片是一塊一塊加載的。這是應爲設置了HTTP請求的長度,從而分塊的加載資源。在請求報文中使用Range屬性,在響應報文中使用Content-Type屬性均可以進行指定必定本身的HTTP請求。

3.8 報文首部總結

image

(圖轉自:http://www.cnblogs.com/xing901022/p/4311987.html)

4.HTTP方法

HTTP 支持幾種不一樣的請求命令,這些命令被稱爲 HTTP 方法(HTTP method)。每 條 HTTP 請求報文都包含一個方法。這個方法會告訴服務器要執行什麼動做(獲取 一個 Web 頁面、運行一個網關程序、刪除一個文件等)。下表是一些常見的HTTP方法:

HTTP方法 描述
GET 從服務器向客戶端發送命名資源
PUT 未來自客戶端的數據存儲到一個命名的服務器資源中去
DELETE 從服務器中刪除命名資源
POST 將客戶端數據發送到一個服務器網關應用程序
HEAD 僅發送命名資源響應中的 HTTP 首部

(GET和POST已在上面討論過了,這裏就不在討論了)

4.一、PUT傳輸文件

PUT方法用於傳輸文件,就像FTP協議的翁建上傳同樣,要求在請求報文的主題中包含文件內容,而後保存到請求URI指定的位置。因爲PUT方法不帶驗證機制,任何人均可以任何人均可以上傳文件,存在安全性問題,所以通常的web網站不適用該方法。

4.二、DELETE刪除文件

DELETE方法用來刪除文件,是與put相反的方法,DELETE方法按照請求url刪除指定的資源。其本質和PUT方法同樣不帶驗證機制,因此建議少用DELETE方法。

4.三、HEAD獲取報文首部

HEAD和GET方法同樣,只是不返回報文主體部分,一般用於確認url的有效性及資源更新的日期時間等。

image

5.HTTPS

5.1 什麼是HTTPS

HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全爲目標的HTTP通道,簡單來講就是是HTTP的安全版本,即在HTTP下加入SSL層,HTTPS的安全基石是SSL,所以加密的詳細內容就須要SSL。 它如今已經被普遍應用,好比GitHub,支付寶,掘金等。

5.2 爲何須要HTTPS

這是因爲HTTP有這麼幾個缺點:

  • 傳輸的時候使用明文,這顯然會被不法者截取幹一些見不得人的勾當。
  • 沒有認證機制,這樣咱們就能夠僞造一些HTTP訪問,這顯然會形成一些困擾。好比Jmeter就是典型的例子,僞造一大堆的HTTP URL而後壓力測試,這也就是DOS攻擊的一種。
  • 沒法驗證報文的完整性,好比一個HTTP的報文已經被不法者截取而且篡改,而服務器端卻沒法驗證。

5.3 HTTP 與 HTTPS 的區別

正是因爲以上這些缺點,HTTPS做出瞭如下一些改變:

  • HTTP 是明文傳輸,HTTPS 經過 SSL\TLS 進行了加密;
  • HTTP 的端口號是 80,HTTPS 是 443;
  • HTTPS 須要到 CA 申請證書,通常免費證書不多,須要交費;
  • -HTTP 的鏈接很簡單,是無狀態的。而 HTTPS 協議則是由 SSL+HTTP; 協議構建的可進行加密傳輸、身份認證的網絡協議,比 HTTP 協議安全

5.4 HTTPS的缺陷

能夠說HTTPS相對於HTTP就是套上了黃金甲的聖鬥士,變了身的奧特曼,沉睡了的毛利小五郎,不只僅提高了安全,還提高了逼格。但HTTPS也有一些缺陷:

  • 通訊的速度變慢,因爲須要加密,一個握手就多了好幾個往返;
  • 對用戶的機器負載的增長。(說出來大家可能不信,咱們學校一到晚上,用HTTPS協議的網站基本上都上不了)
    image

6. HTTP認證

有一些網站須要用戶的登陸從而獲取用戶的我的信息來進行接下來的操做,所以須要隨時知道這些消息,可是確定不能每次都讓用戶輸入用戶密碼,這樣會讓用戶感受很不爽,所以HTTP也自帶了認證的功能,認證方式主要以下:

image

6.1 BASIC認證

其中BASIC認證是最簡單的認證,大體過程以下:

  1. 客戶端訪問某URL。
  2. 服務器端返回401狀態碼,提示用戶輸入用戶名密碼。
  3. 用戶輸入用戶名密碼,經過BASE64編碼傳輸。
  4. 服務器經過認證,返回狀態碼200

但它有如下缺陷:

  1. 僅僅經過BASE64編碼,其實仍是屬於明文傳輸,安全性不高
  2. 有的瀏覽器不支持註銷

6.2 DIGEST認證

正是因爲BASIC認證存在弱點,所以從HTTP/1.1起就有了DIGEST認證,DIGEST認證一樣使用質詢/響應的方式,但不會像BASIC認證那樣直接明文發送密碼。

image

6.3 SSL認證(比較常見)

SSL客戶端認證是藉由HTTPS的客戶端證書完成認證的方式。憑藉客戶端證書認證,服務器可確認訪問是否來自已登陸的客戶端。

SSL客戶端認證的步驟:

  1. 服務器接收到須要認證資源的請求時,服務器會發送CertificateRequest報文,要求客戶端提供客戶端證書。
  2. 客戶端將客戶端證書信息以Client Certificate報文方式發送給服務器。
  3. 服務器驗證客戶端證書驗證經過後才能領取證書內客戶端的公開密鑰,而後開始HTTPS加密通訊。

像支付寶,網銀之類對安全要求很高的網站,在登陸時,都須要下載一個數字認證,這個數字認證就屬於一種SSL客戶端的驗證。但它的缺點也很明顯,須要手動下載,對於如今愈來愈懶的網民們來說會感受很麻煩(包括我)

6.4 表單認證(最經常使用的)

最後一種認證方式是最多見的,咱們能夠經過cookie或session來進行認證。

Session管理和Cookie應用的結合

我前面提到過,HTTP是無狀態協議,沒法實現狀態管理,所以有了cookie。咱們就可使用Cookie來管理Session(會話),以彌補HTTP協議中不存在的狀態管理功能。

認證步驟:

  1. 客戶端把用戶的ID和密碼等相關信息放入報文的實體部分,而後一般以POST請求的方式發送給服務器。
  2. 服務器會發放用以識別用戶的Session ID。經過驗證從客戶端發送過來的登陸信息進行身份認證,將用戶的認證狀態和Session ID綁定後記錄在服務器端。
  3. 客戶端接收到Session ID後,會將其做爲Cookie保存在本地。下次向服務器發送請求時,瀏覽器自動發送Cookie,Session ID會隨之發送到服務器。服務端經過驗證接收到的Session ID識別用戶和其認證狀態,而後用戶就能執行特定的操做了。

參考資料:

  1. 《圖解HTTP》
  2. https://juejin.im/post/59e4c02151882578d02f4aca
  3. http://www.cnblogs.com/xing901022/p/4309840.html
相關文章
相關標籤/搜索