http的GET和POST

本文主要内容

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

1 <html>
2 <form action="http://192.168.1.112/cgi-bin/button.cgi" method="get">
3 <input type="submit" name="button1" value="up"/>
4 <input type="submit" name="button2" value="down"/>
5 <input type="submit" name="button3" value="left"/>
6 <input type="submit" name="button4" value="right"/>
7 </form>
8 </html>

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

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 char *getcgidata(FILE *fp, char *req_method)
 6 {
 7     char *input;
 8     int length;
 9 
10     /* GET */
11     if (strcmp(req_method, "GET") == 0) {
12         /* get方法的数据放在QUERY_STRING中 */
13         input = getenv("QUERY_STRING");    
14         /* 将结果打印到浏览器中 */
15         printf("<p>input:%s</p>", input);
16         return input;
17     /* POST */
18     } else if (strcmp(req_method, "POST") == 0) {
19         length = atoi(getenv("CONTENT_LENGTH"));    
20         /* CONTENT_LENGTH保存POST方法数据的长度 */
21         printf("length:%d\n", length);
22         input = malloc(sizeof(char)*length + 1);
23         /* 从标准输入读取数据 */
24         int i = 0;
25         while (i < length) {
26             input[i] = getc(fp);
27             i++;
28         }
29         input[i] = '\0';
30         printf("<p>input : %s</p>", input);
31         return input;
32     }
33     return NULL;
34 }
35 
36 int main(int argc, char *argv[])
37 {
38     char *input;
39     char *req_method;
40 
41     /* 确定发给服务器数据的类型,需要有一个空行,
42      * 将文本内容空开*/
43     printf("Content-type:text/html\n\n");    
44     /* 从环境变量获取发送过来数据的方法 */
45     req_method = getenv("REQUEST_METHOD");
46     printf("<p>req_method:%s</p>", req_method);
47 
48     input = getcgidata(stdin, req_method);
49 
50     free(input);
51 
52     return 0;
53 }


我是在虚拟机中安装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

 1 <html>
 2 <form action="http://192.168.1.112/cgi-bin/user.cgi" method="POST">
 3 <table>
 4     <tr>
 5         <td>name</td>
 6         <td><input name="name" size="8" /></td>
 7     </tr>
 8     <tr>
 9         <td>country</td>
10         <td><input name="country" size="8" /></td>
11     </tr>
12     <tr>
13         <td>sex</td>
14         <td><input name="sex" size="8" /></td>
15     </tr>
16     <tr>
17         <td>age</td>
18         <td><input name="age" size="8" /></td>
19     </tr>
20     <tr>
21         <td>submit</td>
22         <td><input type="submit" value="submit" size="8"></td>
23     </tr>
24 </table>
25 </form>
26 </html>

程序user.c

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 
 5 typedef struct user_info {
 6     char name[20];
 7     char country[20];
 8     char sex[10];
 9     int  age;
10 } USER;
11 
12 char *get_data(FILE *fp, char *req_method);
13 int parse_data(char *input, USER *user);
14 
15 int main(int argc, char *argv[])
16 {
17     int length;
18     char *input;
19     char *req_method;
20     USER user;
21 
22     printf("content-type: text/html\n\n");
23 
24     printf("<title>user information</title>");
25     printf("<h4>user info</h4>");
26     req_method = getenv("REQUEST_METHOD");
27     input = get_data(stdin, req_method);
28 /* 将获取的数据打印到浏览器中进行验证 */
29     printf("<p>data:%s</p>", input);
30     parse_data(input, &user);
31 
32     /* 解析后的数据打印到浏览器中 */
33     printf("<p>name:%s</p>", user.name);
34     printf("<p>country:%s</p>", user.country);
35     printf("<p>sex:%s</p>", user.sex);
36     printf("<p>age:%d</p>", user.age);
37 
38     free(input);
39 
40     return 0;
41 }    
42 /* 获取数据 */
43 char *get_data(FILE *fp, char *req_method)
44 {
45     char *input;
46     int length;
47 
48     if (strcmp(req_method, "GET") == 0) {
49         input = getenv("QUERY_STRING");    
50         return input;
51     } else if (strcmp(req_method, "POST") == 0) {
52         length = atoi(getenv("CONTENT_LENGTH"));    
53         printf("length:%d\n", length);
54         input = malloc(sizeof(char)*length + 1);
55         int i = 0;
56         while (i < length) {
57             input[i] = getc(fp);
58             i++;
59         }
60         input[i] = '\0';
61         return input;
62     }
63     return NULL;
64 }
65 
66 /* 解析数据 */
67 int parse_data(char *input, USER *user) 
68 {
69     char *str;
70     char *data;
71 
72     /* 分割数据的数据,strtok函数会将制定的分隔符"&"转化为'\0' 
73      * 并返回分割出的字符串的首地址,str指向 "name=tony */
74     str = strtok(input, "&");
75     /* 指针偏移到'='后面,获取有用的数据 */
76     data = strchr(str, '=') + 1;
77     /* 保存数据 */
78     sprintf(user->name,"%s",data);
79 
80     /* str指向country=China */
81     str = strtok(NULL, "&");
82     data = strchr(str, '=') + 1;
83     sprintf(user->country,"%s",data);
84 
85     /* str指向sex=male */
86     str = strtok(NULL, "&");
87     data = strchr(str, '=') + 1;
88     sprintf(user->sex,"%s",data);
89 
90     /* str指向age=23 */
91     str = strtok(NULL, "&");
92     data = strchr(str, '=') + 1;
93     user->age = atoi(data);
94 
95     return 0;
96 }

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下面的数据帧,也是同样的结果。

浏览器输出结果

 

posted @ 2015-09-04 10:25  SuperTao1024  阅读(530)  评论(0编辑  收藏  举报