本文主要内容

1、  GET和POST方法介绍

2、  源代码分析

3、  结果分析

4、  例子
参考及引用:
  http://www.cnblogs.com/zhijianliutang/archive/2012/09/23/2698860.html
  http://www.cnblogs.com/liuzhang/p/3929198.html
  http://www.cnblogs.com/Daniel-G/p/3995854.html
-----------------------------------------------------------------------------------------------------------------

1、GET和POST方法介绍
html发送表单给服务器常用方法有两种:GET和POST。
<1> GET方法发送给服务器的数据保存在服务器的QUERY_STRING环境变量中。读取这个环境变量的值,就可以获得数据。发送的数据就直接接在html信息头的后面,作为数据的一部分,这个后面会说明。
<2> POST方法的数据是放在发送过去的信息体中。其数据的长度保存在服务器的CONTENT_LENGTH环境变量中,数据被重定向到了标准输入,只要从标准输入读取CONTENT_LENGTH长度的数据即可。读取之后提取其中有用的数据。

2、源代码
<1> html
如下,是我写的网页,action属性指定接收并处理这个表单的函数,method指定表单发送的方法。文件名:button.html

 <html>
<form action="http://192.168.1.112/cgi-bin/button.cgi" method="get">
<input type="submit" name="button1" value="up"/>
<input type="submit" name="button2" value="down"/>
<input type="submit" name="button3" value="left"/>
<input type="submit" name="button4" value="right"/>
</form>
</html>

<2> 使用c语言写的cgi,文件名button.c。

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> char *getcgidata(FILE *fp, char *req_method)
{
char *input;
int length; /* GET */
if (strcmp(req_method, "GET") == ) {
/* get方法的数据放在QUERY_STRING中 */
input = getenv("QUERY_STRING");
/* 将结果打印到浏览器中 */
printf("<p>input:%s</p>", input);
return input;
/* POST */
} else if (strcmp(req_method, "POST") == ) {
length = atoi(getenv("CONTENT_LENGTH"));
/* CONTENT_LENGTH保存POST方法数据的长度 */
printf("length:%d\n", length);
input = malloc(sizeof(char)*length + );
/* 从标准输入读取数据 */
int i = ;
while (i < length) {
input[i] = getc(fp);
i++;
}
input[i] = '\0';
printf("<p>input : %s</p>", input);
return input;
}
return NULL;
} int main(int argc, char *argv[])
{
char *input;
char *req_method; /* 确定发给服务器数据的类型,需要有一个空行,
* 将文本内容空开*/
printf("Content-type:text/html\n\n");
/* 从环境变量获取发送过来数据的方法 */
req_method = getenv("REQUEST_METHOD");
printf("<p>req_method:%s</p>", req_method); input = getcgidata(stdin, req_method); free(input); return ;
}

我是在虚拟机中安装ubuntu,并配置apache服务器,在终端编译(注意生成的cgi文件的权限,其他具有可执行权限),并移动到apache服务器的cgi目录/var/www/cgi-bin。将button.html文件移动到/var/www。

gcc button.c –o button.cgi
sudo mv button.cgi /var/www/cgi-bin/
cp button.html /var/www/

3、结果分析

在windows上的浏览器搜索栏中输入“服务器的ip地址/buuton.html”,访问虚拟机中ubuntu上运行的apache服务器。例如我的服务器地址是192.168.1.112,在搜索栏中输入“192.168.1.112/button.html”。当然也可以直接在本地打开button.html文件,就不需要那么麻烦。如下图所示:

点击其中的某个按键,例如down。在搜索栏中可以看到,get的数据是在发送的信息头中,并且是在“?”之后。

使用Colasoft Capsa 7 Enterprise进行抓包,读取HTTP部分的信息。如下图所示,这就是发送给服务器的信息的信息头。

而将html中的method改正post之后,结果又会怎样呢?

点击down,结果如下:

可以看出,POST的数据是放在发送给服务器的数据信息体的内部的。抓包也可以看出。

4、例子

网页user.html

 <html>
<form action="http://192.168.1.112/cgi-bin/user.cgi" method="POST">
<table>
<tr>
<td>name</td>
<td><input name="name" size="8" /></td>
</tr>
<tr>
<td>country</td>
<td><input name="country" size="8" /></td>
</tr>
<tr>
<td>sex</td>
<td><input name="sex" size="8" /></td>
</tr>
<tr>
<td>age</td>
<td><input name="age" size="8" /></td>
</tr>
<tr>
<td>submit</td>
<td><input type="submit" value="submit" size="8"></td>
</tr>
</table>
</form>
</html>

程序user.c

 #include <stdio.h>
#include <stdlib.h>
#include <string.h> typedef struct user_info {
char name[];
char country[];
char sex[];
int age;
} USER; char *get_data(FILE *fp, char *req_method);
int parse_data(char *input, USER *user); int main(int argc, char *argv[])
{
int length;
char *input;
char *req_method;
USER user; printf("content-type: text/html\n\n"); printf("<title>user information</title>");
printf("<h4>user info</h4>");
req_method = getenv("REQUEST_METHOD");
input = get_data(stdin, req_method);
/* 将获取的数据打印到浏览器中进行验证 */
printf("<p>data:%s</p>", input);
parse_data(input, &user); /* 解析后的数据打印到浏览器中 */
printf("<p>name:%s</p>", user.name);
printf("<p>country:%s</p>", user.country);
printf("<p>sex:%s</p>", user.sex);
printf("<p>age:%d</p>", user.age); free(input); return ;
}
/* 获取数据 */
char *get_data(FILE *fp, char *req_method)
{
char *input;
int length; if (strcmp(req_method, "GET") == ) {
input = getenv("QUERY_STRING");
return input;
} else if (strcmp(req_method, "POST") == ) {
length = atoi(getenv("CONTENT_LENGTH"));
printf("length:%d\n", length);
input = malloc(sizeof(char)*length + );
int i = ;
while (i < length) {
input[i] = getc(fp);
i++;
}
input[i] = '\0';
return input;
}
return NULL;
} /* 解析数据 */
int parse_data(char *input, USER *user)
{
char *str;
char *data; /* 分割数据的数据,strtok函数会将制定的分隔符"&"转化为'\0'
* 并返回分割出的字符串的首地址,str指向 "name=tony */
str = strtok(input, "&");
/* 指针偏移到'='后面,获取有用的数据 */
data = strchr(str, '=') + ;
/* 保存数据 */
sprintf(user->name,"%s",data); /* str指向country=China */
str = strtok(NULL, "&");
data = strchr(str, '=') + ;
sprintf(user->country,"%s",data); /* str指向sex=male */
str = strtok(NULL, "&");
data = strchr(str, '=') + ;
sprintf(user->sex,"%s",data); /* str指向age=23 */
str = strtok(NULL, "&");
data = strchr(str, '=') + ;
user->age = atoi(data); return ;
}

user.html放在/var/www/,cgi放到/var/www/cgi-bin

sudo cp user.html /var/www

gcc user.c -o user.cgi

sudo cp user.cgi /var/www/cgi-bin

浏览器输入:

点击submit,发送数据,抓包,可以知道post的数据信息,发送的数据保存在信息体中。

查看colasoft下面的数据帧,也是同样的结果。

浏览器输出结果

随机推荐

  1. Storm 简单介绍

    Nimbus :负责资源分配和任务调度, 把任务相关的元信息写入Zookeeper 对应文件夹. Supervisor :负责接受nimbus 分配的任务,启动和停止属于自己管理的worker 进程. ...

  2. 修改Excel默认模版(启动模版和新建Sheet模版)

    Office 2013 1.  C:\Windows\ShellNew\EXCEL12.XLSX 设置好格式后另存为, 然后复制过来覆盖掉,如果覆盖不了,注意修改所有者权限 2. 新建文件保存为模版文 ...

  3. CheckedComboBoxEditExtension

    public static class CheckedComboBoxEditExtension { public static void BindData(this CheckedComboBoxE ...

  4. mysql (已解决p)MYSQL5.7启动不了,本地计算机上的 MySQL57 服务启动后停止。

    找到目录E:\AppServ\MySQL\data 备份data中的数据,然后删除掉data中所有的东西(如果删除不掉请在进程中找到mysqld.exe并且关闭) 打开CMD cd E:\AppSer ...

  5. 统计学习方法:支撑向量机(SVM)

    作者:桂. 时间:2017-05-13  21:52:14 链接:http://www.cnblogs.com/xingshansi/p/6850684.html 前言 主要记录SVM的相关知识,参考 ...

  6. Android Studio 2.2 Record Espresso Test

    Android Studio 已经更新到了2.2,在 Run 中发现了 Record Espresso Test 功能,很强大,但是不稳定. 尝试了下在 Android 6.0 上的登录页面,可以通过 ...

  7. 原来的debussy可以在win7的64位系统下运行吗

    可以的,首先下载两个DLL:msvcr71.dll和msvcp71.dll,然后破解一下就可以了. https://zhidao.baidu.com/question/2419893614880017 ...

  8. SICP-Exercise 1.5

    Exercise 1.5.  Ben Bitdiddle has invented a test to determine whether the interpreterhe is faced wit ...

  9. ubantu 文件解压缩

    对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕.别个不说,单单就压缩文件为例,我们知道在Windows下最常见 的压缩文件就只有两种,一是,zip,另一个是.rar. ...

  10. 每日英语:First Offer: Take It Or Keep Waiting?

    Anyone who has searched for a job fresh out of college knows how difficult it is to get that first j ...