讓你輕鬆瞭解什麼是HTTP協議,什麼是URI

1.Http簡介

HTTP是一種無狀態、由文本構成的請求-響應(request-response)協議,這種協議使用的是客戶端-服務器(client-server)計算模型。
請求-響應是兩臺計算機進行通信的基本方式,其中一臺計算機會向另一臺計算機發送請求,而接收到請求的計算機則會對請求進行響應。在客戶端-服務端計算模型中,發送請求的一方(客戶端)負責向返回響應的一方(服務器)發起會話,而服務端則負責爲客戶提供服務。在HTTP協議中,客戶端也被稱爲用戶代理(user-agent),而服務器則通常會被稱爲Web服務器。
HTTP是以純文本方式而不是二進制方式發送和接收協議數據的。

2. CGI

CGI(Common Gateway Interface)通用網關接口。簡單理解,可以認爲CGI是Web服務器和一個獨立的進程之間的協議,它會把HTTP請求Request的Header頭設置成進程的環境變量,HTTP請求的Body正文設置成進程的標準輸入,進程的標準輸出設置爲HTTP響應Response,包含Header頭和Body正文。

3. HTTP請求

HTTP是一種請求-響應協議,協議涉及的所有事情都以一個請求開始。HTTP請求跟其他所有HTTP保溫(message)一樣,都由一系列文本行組成,這些文本行會按照以下順序進行排列:
(1)請求行(request-line);
(2)零個或任意多個請求首部(header);
(3)一個空行;
(4)可選的報文主體(body)。
如下圖:
在這裏插入圖片描述
請求行的第一個單詞爲請求方法,之後跟着的是統一資源標識符(Uniform Resource Identifier, URI)以及所使用的HTTP版本。位於請求行之後的兩個文本行爲請求的首部。

3.1 請求方法

請求方法是請求行中的第一個單詞,他指明瞭客戶端想要對資源執行的操作。HTTP0.9只有GET一個方法,HTTP1.0添加了POST方法和HEAD方法,而HTTP1.1則添加了PUT、DELETE、OPTIONS、TRACE和CONNECT這五個方法,並允許開發者自行添加更多方法。
各個HTTP方法的作用說明如下:

  • GET 命令服務器返回指定的資源
  • HEAD 與GET方法的作用類似,唯一的不同在於這個方法不要求服務器返回報文的主體。這個方法通常用於在不獲取報文主體的情況下,取得響應的首部。
  • POST 命令服務器將報文主體中的數據傳遞給URI指定的資源,至於服務器具體會對這些數據執行什麼動作則取決於服務器本身。
  • PUT 命令服務器將報文主題中的數據設置爲URI指定的資源。如果URI指定的位置上已經有數據存在,那麼使用報文主體中的數據去代替已有的數據。如果資源尚未存在,那麼URI指定的位置上新創建一個資源。
  • DELETE 命令服務器刪除URI指定的資源
  • TRACE 命令服務器返回請求本身。通過這個方法,客戶端可以知道介於他和服務器之間的其他服務器是如何處理請求的。
  • OPTIONS 命令服務器返回它支持的HTTP方法列表。
  • CONNECT 命令服務器與客戶端建立一個網絡連接。這個方法通常用於設置SSL隧道以開啓HTTPS功能。
  • PATCH 命令服務器使用報文主體中的數據對URI指定的資源進行修改。
3.2 安全的請求方法

如果一個HTTP方法只要求服務器提供信息而不會對服務器的狀態做任何修改,那麼這個方法就是安全的(safe)。GET、HEAD、OPTIONS和TRACE都不會對服務器的狀態進行修改,所以他們都是安全的方法。

3.3 冪等的請求方法

如果一個HTTP方法在使用相同的數據進行第二次調用的時候,不會對服務器的狀態造成任何改變,那麼設個方法就是冪等的。根據安全的方法的定義,因爲多有安全的方法都不會修改服務器狀態,所以他們天生就是冪等的。

PUT和DELETE雖然不安全,但卻是冪等的,因爲他們在進行第二次調用的時候都不會改變服務器的狀態:因爲服務器在執行第一個PUT請求之後URI指定的資源已經更新或者創建出來了,所以針對同一個資源的第二次PUT請求只會執行服務器已經執行過的動作;與此類似,雖然服務器對於同一個資源的第二次PUT請求只會執行服務器已經執行過的動作;與此類似,雖然服務器對於同一個資源的第二次DELETE請求肯能會返回一個錯誤,但這個請求並不會改變服務器的狀態。

3.4 瀏覽器對請求方法的支持

GET方法是最基本的HTTP方法,它負責從服務器上獲取內容,所有瀏覽器都支持這個方法。POST方法從HTML2.0開始可以通過添加HTML表單來實現:HTML的form標籤有一個名爲method的屬性,用戶通過將這個屬性的值設置爲get或者post來指定要使用那個方法。HTML不支持除GET和POST之外的其他HTTP方法。

但是,現在流行的瀏覽器通常都不會只支持HTML一種數據格式——用戶可以使用XMLHttpRequest(XHR)來或得對PUT方法和DELETE方法的支持。XHR是一系列瀏覽器API,這些API通常由JavaScript包裹(實際上XHR就是一個名爲XMLHttpRequest的瀏覽器對象)。XML允許程序員向服務器發送HTTP請求,並且跟「XMLHttpRequest」這個名字所暗示的不一樣,這項技術並不僅僅侷限於XML格式——包括JSON以及純文本在內的任何格式的請求和響應都可以通過XHR發送。

3.5 請求首部

HTTP請求方法定義了發送請求的客戶端想要執行的動作,而HTTP請求的首部則記錄了與請求本身及客戶端有關的信息。請求的首部由熱議多個冒號隔開的純文本鍵值對組成,最後以回車(CR)和換行(LF)結尾。
常見的請求首部:

首部字段 作用描述
Accept 客戶端在HTTP響應中能夠接收的內容類型。比如說,客戶端可以通過Accept:text/html這個首部,告知服務器自己希望在響應的主體中收到HTML類型的內容
Accept-Charset 客戶端要求服務器使用的字符集編碼。比如客戶端可以通過Accept-Charset:uft-8這個首部,告知服務器自己希望響應的主體使用UTF-8字符集。
Authorization 這個首部用於向服務器發送基本的身份驗證證書
Cookie 客戶端應該在這個首部中把服務器之前設置的所有cookie回傳給服務器。比如說,如果服務器之前在瀏覽器上設置了3個cookie,那麼Cookie首部字段將在一個字符串裏面包含這三個cookie,並使用分號對這些cookie進行分割。以下是一個Cookie首部示例:Cookie: my_first_cookie=hello; my_second_cookie=world
Content-Length 請求主體的字節長度
Content-Type 當請求包含主體的時候,這個首部用於記錄主體內容的類型。在發送POST或PUT請求時,內容的類型默認爲x-www-form-urlen-coded,但是在上傳文件時,內容的類型應該設置爲multipart/form-data(上傳文件這一操作可以通過將input標籤的類型設置爲file來實現)
Host 服務器的名字以及端口號。如果這個首部沒有記錄服務器的端口號,就表示服務器使用的是80端口。
Referrer 發送請求的頁面所在的地址
User-Agent 對發起的客戶端進行描述

4. HTTP響應

HTTP響應報文是對HTTP請求報文的回覆。跟HTTP請求一樣,HTTP響應也由一系列文本行組成,其中包括:

  • 一個狀態行;
  • 零個或任意數量的響應首部,
  • 一個空行;
  • 一個可選的報文主體。
    如下圖:
    在這裏插入圖片描述
    HTTP響應的第一行爲狀態行,這個文本行包括了狀態碼( status code )和相應的原因短語( reason phrase ),原因短語對狀態碼進行了簡單的描述。除此之外,這個例子中的HTTP響應還包含了一個HTML格式的報文主體。
4.1 響應狀態碼:

HTTP響應狀態碼總共有5種類型,他麼分別以不同的數字作爲前綴,如下表:

狀態碼類型 作用描述
1XX 情報狀態碼。服務器通過這些狀態碼來告知客戶端,自己已經接收到了客戶端發送的請求,並且已經對請求進行了處理。
2XX 成功狀態碼。這些狀態碼說明服務器已經接收到了客戶端發送的請求,並且已經成功的對請求進行了處理。這類狀態碼的標準響應爲「200 OK」
3XX 重定向狀態碼。這些狀態碼錶示服務器已經接收到了客戶端發送的請求,並且已經處理了請求,但是爲了完成指定的動作,客戶端還需要在做一切其他的 工作。這類狀態碼大多用於實現URL重定向。
4XX 客戶端錯誤狀態碼。這類狀態碼說明客戶端發送的請求出現了某些問題。在這一類型的狀態碼種,最常見的就是「404 Not Found」,這個狀態碼錶示服務器無法從請求的URL中找到客戶端想要的資源。
5XX 服務器錯誤狀態碼。當服務器因爲某些原因而無法正確的處理請求時,服務器就會使用這類狀態碼來通知客戶端。這一類狀態碼中,最常見的就是」500 Internal Server Error「狀態碼。
4.2 響應首部

響應首部跟請求首部一樣,都是由冒號分隔的純文本鍵值對組成,並且同樣以(CR)和換行符(LF)結尾。下表爲常見的響應首部:

首部字段 作用描述
Allow 告知客戶端,服務器支持那些請求方法
Content-Length 響應主體的字節長度
Content-Type 如果響應包含可選的主體,那麼這個首部記錄的就是主體內容的類型
Date 以格林尼治標準時間(GMT)格式記錄的當前事件
Location 這個首部僅在重定向時使用,他會告知客戶端接下來應該向那個URL發送請求
Server 返回響應的服務器的域名
Set-Cookie 在客戶端裏面設置一個Cookie。這個相應裏面可以包含多個Set-Cookie的首部。
W-W-W-Authenticate 服務器通過這個首部告知客戶端,在Authorization請求首部中應該提供哪些類型的身份驗證信息。服務器常常會把這個首部與「401 Unauthorized」狀態行一同發送。除此之外,這個首部還會向服務器許可的認證授權模式(schema)提供驗證信息

5.URI

URI(Uniform Resource Location, 統一資源定位符)是一個涵蓋性術語,它包含了URN(Uniform Resource Name, 統一資源名稱)和URL,並且這兩者也擁有相似的語法和格式。

URI的一般格式爲:<方案名稱>:<分層部分>[ ? <查詢參數> ][ # <片段> ]

URI中的方案名稱(scheme name)記錄了URI正在使用的方案,它定義了URI其餘部分的結構。因爲URI是一種非常常用的資源標識方式,所以它擁有大量的方案可供使用。

URI的分層部分(hierarchical part)包含了資源的識別信息,這些信息會以分層的方式進行組織。如果分層部分以雙斜線(//)開頭,那麼說明它包含了可選的用戶信息,這些信息將以@符號結尾,後跟分層路徑。不帶用戶信息的分層部分就是一份單純的路徑,每個路徑都由一連串的分段(segment)組成,各個分段之間使用但斜槓(/)分隔。

在URI的各個部分當中,只有「方案名稱」和「分層部分」是必須的。以問好(?)爲前綴的查詢參數(query)是可選的,這些參數用於包含無法使用分層方式表示的其他信息。多個查詢參數會被組織成一連串的鍵值對,各個鍵值對之間只用&符號分割。

URI的零一個可選部分爲片段(fragment),片段使用井號(#)作爲前綴,它可以對URI定義的資源中的次級資源(secondary resource)進行標識。當URI包含查詢參數時,URI的片段將被放到查詢參數之後。因爲URI的片段是由客戶端負責處理的,所以Web瀏覽器在將URI發送給服務器之前,一般都會先把URI中的片段移除掉。如果程序員想要取得URI片段,那麼可以通過JavaScript或者某個HTTP客戶端庫,將URI片段包含在一個GET請求裏面。