CGI(Common Gateway Interface)不涉及具體的網絡通訊報文格式,它定義的是?Web服務器與外部程序之間的數據交互方式,而不是像HTTP或FastCGI那樣的二進制協議。下面分幾個方面詳細說明:
1. CGI 的交互方式(非報文協議)
CGI 的核心是?通過環境變量和標準輸入/輸出(stdin/stdout)傳遞數據,不依賴特定的二進制報文結構。具體流程:
(1) Web服務器傳遞給CGI程序的數據
-
環境變量(由服務器設置,CGI程序讀取):
-
REQUEST_METHOD
:HTTP方法(GET/POST等)。 -
QUERY_STRING
:URL中的查詢參數(如?name=foo
)。 -
CONTENT_TYPE
:請求體的MIME類型(如application/json
)。 -
CONTENT_LENGTH
:請求體的字節長度。 -
其他HTTP頭會轉為
HTTP_*
格式(如HTTP_USER_AGENT
)。
-
-
標準輸入(stdin):
-
如果是POST/PUT請求,請求體會通過
stdin
傳遞給CGI程序,需根據CONTENT_LENGTH
讀取指定字節數。
-
(2) CGI程序返回給服務器的數據
-
標準輸出(stdout):
-
CGI程序必須?先輸出HTTP頭,后跟響應體,用空行分隔(
\n\n
)。 -
示例:
print("Content-Type: text/html\n") # HTTP頭 print() # 空行 print("<h1>Hello CGI</h1>") # 響應體
-
2. 對比真正的“報文協議”(如FastCGI)
CGI?不定義任何二進制或文本報文格式,而其他協議(如FastCGI、SCGI)會嚴格規定報文結構:
協議 | 是否定義報文格式 | 示例報文結構 | 用途 |
---|---|---|---|
CGI | ? 否 | 無,靠環境變量和stdin/stdout | 通用但性能低 |
FastCGI | ? 是 | 二進制報文(類型+請求ID+內容長度等) | 高性能持久化連接 |
SCGI | ? 是 | 文本協議(CONTENT_LENGTH?數據... ) | 簡化版FastCGI |
HTTP | ? 是 | GET /path HTTP/1.1??Host:... | 客戶端與服務器通信 |
FastCGI 報文示例(二進制協議)
# 請求頭報文(16字節固定格式) typedef struct {unsigned char version; // 協議版本unsigned char type; // 報文類型(如BEGIN_REQUEST)unsigned char requestId[2];// 請求IDunsigned char contentLength[2]; // 內容長度unsigned char paddingLength; // 填充長度unsigned char reserved; } FCGI_Header;# 實際數據(如HTTP參數)跟在報文頭后
3. 為什么CGI不需要報文格式?
-
簡單性:CGI設計初衷是跨語言通用,直接利用操作系統的標準輸入/輸出和環境變量。
-
無持久連接:每次請求結束進程退出,無需維護復雜狀態。
-
文本友好:HTTP本身是文本協議,CGI直接復用其特性(如環境變量映射HTTP頭)。
4. 如果想看CGI的“實際數據流”
雖然CGI沒有報文,但可以通過抓包或日志觀察數據流:
(1) 客戶端發送的HTTP請求
POST /cgi-bin/script.py HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded Content-Length: 12name=foo&age=20
(2) Web服務器傳遞給CGI程序的數據
-
環境變量:
REQUEST_METHOD=POST CONTENT_TYPE=application/x-www-form-urlencoded CONTENT_LENGTH=12 QUERY_STRING= # GET請求時才有
-
標準輸入(stdin):
name=foo&age=20
(3) CGI程序返回的響應
-
標準輸出(stdout):
Content-Type: text/html<html>Hello, foo!</html>
5. 總結
-
CGI不定義通訊報文,而是通過?環境變量 + stdin/stdout?傳遞數據。
-
真正的報文協議(如FastCGI/SCGI)會嚴格規定二進制或文本格式,適合高性能場景。
-
CGI的劣勢:每次請求啟動新進程,性能低下,適合歷史學習或簡單腳本,現代Web開發已轉向FastCGI(PHP-FPM)、WSGI(Python)等方案。