You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++ CGI程序中获取GET/POST变量?(Apache+Ubuntu环境)

在Ubuntu 22.04.1 Apache上用C++ CGI处理表单GET/POST数据的基础方法

核心原理说明

表单的GET和POST数据不会直接作为环境变量存在,需根据请求方式分别处理:

  • GET请求:表单数据拼接为key=value&key2=value2格式,放在URL查询字符串中,Apache会将该字符串存入QUERY_STRING环境变量。
  • POST请求:表单数据通过HTTP请求体发送,Apache将数据传递给CGI程序的标准输入,同时通过CONTENT_LENGTH环境变量告知数据字节长度。

完整实现代码(仅用标准库)

以下代码包含URL解码、键值对解析,以及GET/POST请求的处理逻辑:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// URL解码:处理%xx编码和+替换为空格
void url_decode(char *str) {
    char *dest = str;
    while (*str) {
        if (*str == '+') {
            *dest = ' ';
        } else if (*str == '%' && isxdigit(str[1]) && isxdigit(str[2])) {
            // 十六进制转十进制
            int hex_val = 0;
            hex_val += isdigit(str[1]) ? str[1] - '0' : toupper(str[1]) - 'A' + 10;
            hex_val *= 16;
            hex_val += isdigit(str[2]) ? str[2] - '0' : toupper(str[2]) - 'A' + 10;
            *dest = (char)hex_val;
            str += 2;
        } else {
            *dest = *str;
        }
        str++;
        dest++;
    }
    *dest = '\0';
}

// 解析键值对字符串并输出
void parse_form_data(char *data) {
    if (!data || *data == '\0') {
        printf("无表单数据\n");
        return;
    }

    char *pair = strtok(data, "&");
    while (pair != NULL) {
        char *eq_pos = strchr(pair, '=');
        if (eq_pos != NULL) {
            *eq_pos = '\0';
            char *key = pair;
            char *value = eq_pos + 1;
            url_decode(key);
            url_decode(value);
            printf("%s: %s\n", key, value);
        } else {
            url_decode(pair);
            printf("%s: 无值\n", pair);
        }
        pair = strtok(NULL, "&");
    }
}

int main() {
    // 必须先输出HTTP响应头
    printf("Content-type:text/plain\n\n");

    // 获取请求方法
    char *method = getenv("REQUEST_METHOD");
    if (!method) {
        printf("无法获取请求方法\n");
        return 1;
    }

    printf("请求方法: %s\n", method);
    printf("--- 表单数据 ---\n");

    if (strcmp(method, "GET") == 0) {
        // 处理GET请求:读取QUERY_STRING
        char *query_str = getenv("QUERY_STRING");
        parse_form_data(query_str);
    } else if (strcmp(method, "POST") == 0) {
        // 处理POST请求:读取标准输入
        char *content_length_str = getenv("CONTENT_LENGTH");
        if (!content_length_str || *content_length_str == '\0') {
            printf("CONTENT_LENGTH环境变量无效\n");
            return 1;
        }

        int content_length = atoi(content_length_str);
        if (content_length <= 0) {
            printf("表单数据长度无效\n");
            return 1;
        }

        // 分配内存存储POST数据
        char *post_data = (char*)malloc(content_length + 1);
        if (!post_data) {
            printf("内存分配失败\n");
            return 1;
        }

        // 读取数据
        int bytes_read = fread(post_data, 1, content_length, stdin);
        if (bytes_read != content_length) {
            printf("读取POST数据不完整\n");
            free(post_data);
            return 1;
        }
        post_data[content_length] = '\0';

        parse_form_data(post_data);
        free(post_data);
    } else {
        printf("不支持的请求方法\n");
    }

    printf("--- 处理完成 ---\n");
    return 0;
}

编译与部署步骤

  1. 编译代码:将代码保存为form_handler.cpp,编译为CGI程序:
    g++ form_handler.cpp -o /var/www/html/cgi-bin/form_handler.cgi
    
  2. 设置权限:确保程序可执行:
    chmod +x /var/www/html/cgi-bin/form_handler.cgi
    
  3. Apache配置:
    • 启用CGI模块:sudo a2enmod cgi
    • 编辑网站配置文件/etc/apache2/sites-available/000-default.conf,确认以下内容:
      ScriptAlias /cgi-bin/ /var/www/html/cgi-bin/
      <Directory /var/www/html/cgi-bin/>
          AllowOverride None
          Options +ExecCGI
          Require all granted
      </Directory>
      
    • 重启Apache:sudo systemctl restart apache2

测试用HTML表单

<!doctype html>
<html>
<head>
<title>CGI表单测试</title>
</head>
<body>
<h2>POST请求测试</h2>
<form action="cgi-bin/form_handler.cgi" method="post">  
    <input type="text" name="username" value="SampleName">
    <input type="password" name="Password" value="SamplePass"> 
    <button type="submit" name="Submit">提交POST</button>
</form>

<hr>

<h2>GET请求测试</h2>
<form action="cgi-bin/form_handler.cgi" method="get">  
    <input type="text" name="username" value="SampleName">
    <input type="password" name="Password" value="SamplePass"> 
    <button type="submit" name="Submit">提交GET</button>
</form>
</body>
</html>

内容的提问来源于stack exchange,提问作者Black plague

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 00:50:49