首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

CGI 通用網關接口全解析:原理、配置、C 語言實現與 Apache 部署實戰

     編輯:關於C語言

從原理到落地:CGI 協議詳解與 C 語言開發完整指南

CGI (Common Gateway Interface) 是 Web 服務器與外部程序交互的標準協議,將靜態頁面變為動態交互應用。雖然現代框架(FastCGI、uWSGI、Node.js 等)性能更高,但 CGI 仍是理解 Web 後端本質的最佳切入點。本文涵蓋協議原理、服務器配置、環境變量、C 語言開發實例及 Apache 部署全流程。

CGI 工作流程

  1. 用戶提交表單 → 瀏覽器發送 HTTP 請求
  2. Web 服務器接收,根據規則啟動 CGI 程序,設置環境變量
  3. CGI 程序從 `stdin`/`環境變量` 讀取輸入,處理業務邏輯
  4. CGI 程序向 `stdout` 輸出 HTTP 響應(含 Header + Body)
  5. 服務器捕獲輸出,轉發給瀏覽器

關鍵環境變量(子集)

Apache CGI 配置(以 USBWebServer 為例)

# httpd.conf
ScriptAlias /cgi-bin/ "{rootdir}/cgi-bin/"

    AllowOverride None
    Options ExecCGI
    Order allow,deny
    Allow from all

AddHandler cgi-script .exe .pl .cgi

將編譯好的 `.exe` 放入 `cgi-bin` 目錄,瀏覽器訪問 `https://127.0.0.1:8080/cgi-bin/index.cgi`。

C 語言 CGI 開發實戰三部曲

1. 入口頁面 `index.html`(表單演示)

M: N:
留言:

2. GET 處理 `mult.cgi`(乘法計算器)

#include 
#include 

int main() {
    printf("Content-Type:text/html\n\n"); // 必須:HTTP Header 結束雙換行
    printf("乘法結果

乘法結果

"); char *data = getenv("QUERY_STRING"); long m, n; if (!data) printf("

錯誤:無輸入數據"); else if (sscanf(data, "m=%ld&n=%ld", &m, &n) != 2) printf("

錯誤:參數格式非法"); else printf("

%ld * %ld = %ld", m, n, m * n); printf(""); return 0; }

3. POST 處理 `collect.cgi`(留言存儲)

#include 
#include 

#define MAXLEN 80
#define DATAFILE "../data/data.txt"

void url_decode(char *src, char *dst) { // 簡易 URL 解碼
    for (; *src; src++, dst++) {
        if (*src == '+') *dst = ' ';
        else if (*src == '%') {
            int code; sscanf(src+1, "%2x", &code); *dst = code; src += 2;
        } else *dst = *src;
    }
    *dst = '\0';
}

int main() {
    printf("Content-Type:text/html\n\n");
    printf("Response");

    char *lenstr = getenv("CONTENT_LENGTH");
    long len = lenstr ? atol(lenstr) : 0;
    if (len <= 0 || len > MAXLEN) {
        printf("

提交錯誤"); } else { char input[MAXLEN+10], data[MAXLEN+10]; fgets(input, len+1, stdin); // 從 stdin 讀取 POST 體 url_decode(input + 5, data); // 跳過 "data=" FILE *f = fopen(DATAFILE, "a"); if (f) { fputs(data, f); fclose(f); printf("

留言已保存"); } else printf("

系統錯誤"); } printf(""); return 0; }

4. 查看留言 `viewdata.cgi`

#include 
#include 
#define DATAFILE "../data/data.txt"

int main() {
    FILE *f = fopen(DATAFILE, "r");
    if (!f) {
        printf("Content-Type:text/html\n\n

無法打開文件"); return 0; } printf("Content-Type:text/plain\n\n"); // 純文本輸出 int ch; while ((ch = getc(f)) != EOF) putchar(ch); fclose(f); return 0; }

編譯部署清單

  1. 安裝 GCC(MinGW / Cygwin / Linux 原生)
  2. `gcc mult.c -o mult.exe` 等生成可執行文件
  3. 複製 `.exe` 到 Apache `cgi-bin` 目錄
  4. 確保 `data.txt` 目錄可寫(Windows 需檢查權限)
  5. 瀏覽器測試各功能

CGI 與現代替代方案對比

變量含義示例
REQUEST_METHODGET/POSTPOST
QUERY_STRINGGET 參數字符串m=3&n=4
CONTENT_LENGTHPOST 數據長度27
CONTENT_TYPEPOST 數據類型application/x-www-form-urlencoded
HTTP_USER_AGENT客戶端標識Mozilla/5.0...
REMOTE_ADDR客戶端 IP192.168.1.100
SERVER_NAME服務器主機名localhost

學習 CGI 能深刻理解「請求-響應」本質、環境變量傳遞、標準流重定向,為掌握高性能框架打下堅實基礎。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方案進程模型性能適用場景
CGI請求即 fork/exec低(進程開銷大)教學、極低流量、簡單腳本
FastCGI常駐進程池高PHP/Python 傳統部署
uWSGI/Gunicorn預fork/線程池高Python Web 應用
內嵌服務器進程內路由最高Go/Node.js/Java/Spring Boot