C语言构建WEB管理系统(四):CGI程序解析POST数据

【版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途】

这一节我们将介绍如何解析POST方式提交的表单数据,在前面说过POST提交的数据没有放在QUERY_STRING环境变量中,我们将上一节的示例表单直接改为POST方式如下:

    <body>
        <p> 登录信息: </p>
        <!--<form action="/cgi-bin/print.cgi">-->
        <form action="/cgi-bin/print.cgi" method="post">
            用户名:
            <input type="text" name="用户名"/> <br />
            密码:
            <input type="password" name="密码" /> <br />
            <input type="radio" name="语言" value="English"/> English <br />
            <input type="radio" name="语言" value="Chinese"/> 简体中文
            <input type="hidden" name="sessionid" value="1234567890"/> <br />
            <input type="submit" value="登录"> <br />
        </form>
    </body>

所以要获取POST方式提交的数据,需要首先从环境变量 CONTENT_LENGTH中获取数据长度,然后再从标准输入中去读该长度个字节,最后再按照上一节解析GET方式数据一样去解析数据。下面为获取POST数据集解析数据代码: 
int main(int argc, const char *argv[])
{
    char     *data = NULL, *data_len_str = NULL;
    int      data_len, read_len;
    fprintf(stdout, "Content-Type: text/html\r\n\r\n");
    data_len_str = getenv("CONTENT_LENGTH");
    if (NULL == data_len_str) {
        data_len_str = "";
    }
    data_len = atoi(data_len_str);
    if (data_len < 0) {
       return -1;
    }
    data = (char *)malloc(data_len);
    if (NULL == data) {
        return -1;
    }
    read_len = fread(data, 1, data_len, stdin);
    if (read_len != data_len) {
        return -1;
    }
    fprintf(stdout, "<HTML>\n");
    fprintf(stdout, "<HEAD>\n");
    fprintf(stdout, "<TITLE>CGI解析POST数据</TITLE>\n");
    fprintf(stdout, "<HEAD>\n");
    fprintf(stdout, "<BODY>\n");
    fprintf(stdout, "<H3>以下为解析后数据</H3>\n");
    sln_cgi_content_parse(data, data_len);
    fprintf(stdout, "本网页由CGI自动生成!\n");
    fprintf(stdout, "</BODY>");
    fprintf(stdout, "</HTML>");
    free(data);
    return 0;
}


将编译后的程序放在/cgi-bin/目录下,在页面填好数据按”提交“按钮页面显示如下:
说明POST数据已经解析成功!
  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
解析form-data数据,需要先了解一下form-data的格式。form-data是一种常见的HTTP POST请求体格式,用于向服务器发送表单数据。其格式如下: ``` Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryxyzabc ------WebKitFormBoundaryxyzabc Content-Disposition: form-data; name="field1" value1 ------WebKitFormBoundaryxyzabc Content-Disposition: form-data; name="field2"; filename="example.txt" Content-Type: text/plain file contents ------WebKitFormBoundaryxyzabc-- ``` 其中,boundary指定了分隔符。在解析form-data数据时,需要按照分隔符将数据分割成多个部分,然后对每个部分进行解析。 以下是一个简单的C语言代码示例,用于解析form-data数据: ```c #include <stdio.h> #include <string.h> int main() { char *data = "------WebKitFormBoundaryxyzabc\r\nContent-Disposition: form-data; name=\"field1\"\r\n\r\nvalue1\r\n------WebKitFormBoundaryxyzabc\r\nContent-Disposition: form-data; name=\"field2\"; filename=\"example.txt\"\r\nContent-Type: text/plain\r\n\r\nfile contents\r\n------WebKitFormBoundaryxyzabc--\r\n"; char *boundary = "------WebKitFormBoundaryxyzabc"; // find the first part boundary char *part_start = strstr(data, boundary); if (part_start == NULL) { printf("Error: cannot find the first part boundary.\n"); return 1; } // parse each part while (1) { // find the next part boundary char *part_end = strstr(part_start + strlen(boundary), boundary); if (part_end == NULL) { printf("Error: cannot find the next part boundary.\n"); return 1; } // get the part data char *part_data_start = part_start + strlen(boundary) + 2; // skip CRLF char *part_data_end = part_end - 2; // skip CRLF int part_data_len = part_data_end - part_data_start; char part_data[part_data_len + 1]; memcpy(part_data, part_data_start, part_data_len); part_data[part_data_len] = '\0'; // parse the part data char *name_start = strstr(part_start, "name=\""); if (name_start == NULL) { printf("Error: cannot find the name attribute.\n"); return 1; } name_start += 6; // skip "name=\"" char *name_end = strstr(name_start, "\""); if (name_end == NULL) { printf("Error: cannot find the end of the name attribute.\n"); return 1; } int name_len = name_end - name_start; char name[name_len + 1]; memcpy(name, name_start, name_len); name[name_len] = '\0'; char *filename_start = strstr(part_start, "filename=\""); if (filename_start != NULL) { // this is a file part filename_start += 10; // skip "filename=\"" char *filename_end = strstr(filename_start, "\""); if (filename_end == NULL) { printf("Error: cannot find the end of the filename attribute.\n"); return 1; } int filename_len = filename_end - filename_start; char filename[filename_len + 1]; memcpy(filename, filename_start, filename_len); filename[filename_len] = '\0'; printf("Part name: %s, filename: %s, data: %s\n", name, filename, part_data); } else { // this is a regular part printf("Part name: %s, data: %s\n", name, part_data); } part_start = part_end; if (part_start[2] == '-') { break; // end of data } } return 0; } ``` 该代码将form-data数据解析为多个部分,并对每个部分进行解析。如果是文件部分,会输出文件名和文件内容;否则,只输出表单字段名和值。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值