CGI编程完全手册(个人学习笔记)

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

CGI一.基本原理CGI:通用网关接口(CommonGatewayInterface)是一个Web服务器主机提供信息服务的标准接口。通过CGI接口,Web服务器就能够获取客户端提交的信息,转交给服务器端的CGI程序进行处理,最后返回结果给客户端。组成CGI通信系统的是两部分:一部分是html页面,就是在用户端浏览器上显示的页面。另一部分则是运行在服务器上的Cgi程序。它们之间的通讯方式如下图:服务器和客户端之间的通信,是客户端的浏览器和服务器端的http服务器之间的HTTP通信,我们只需要知道浏览器请求执行服务器上哪个CGI程序就可以了,其他不必深究细节,因为这些过程不需要程序员去操作。服务器和CGI程序之间的通讯才是我们关注的。一般情况下,服务器和CGI程序之间是通过标准输入输出来进行数据传递的,而这个过程需要环境变量的协作方可实现。1.服务器将URL指向一个应用程序2.服务器为应用程序执行做准备3.应用程序执行,读取标准输入和有关环境变量4.应用程序进行标准输出对于Windows系统而言,还可以通过profile文件进行数据传输(如ini文件),但在这里不做研究。环境变量在CGI中有着重要的地位!每个CGI程序只能处理一个用户请求,所以在激活一个CGI程序进程时也创建了属于该进程的环境变量。服务器客户端CGI程序HTTP通信标准输入输出(环境变量)二.环境变量对于CGI程序来说,它继承了系统的环境变量。CGI环境变量在CGI程序启动时初始化,在结束时销毁。当一个CGI程序不是被HTTP服务器调用时,它的环境变量几乎是系统环境变量的复制。当这个CGI程序被HTTP服务器调用时,它的环境变量就会多了以下关于HTTP服务器、客户端、CGI传输过程等项目。与请求相关的环境变量REQUEST_METHOD服务器与CGI程序之间的信息传输方式QUERY_STRING采用GET时所传输的信息CONTENT_LENGTHSTDIO中的有效信息长度CONTENT_TYPE指示所传来的信息的MIME类型CONTENT_FILE使用WindowsHTTPd/WinCGI标准时,用来传送数据的文件名PATH_INFO路径信息PATH_TRANSLATEDCGI程序的完整路径名SCRIPT_NAME所调用的CGI程序的名字与服务器相关的环境变量GATEWAY_INTERFACE服务器所实现的CGI版本SERVER_NAME服务器的IP或名字SERVER_PORT主机的端口号SERVER_SOFTWARE调用CGI程序的HTTP服务器的名称和版本号与客户端相关的环境变量REMOTE_ADDR客户机的主机名REMOTE_HOST客户机的IP地址ACCEPT例出能被次请求接受的应答方式ACCEPT_ENCODING列出客户机支持的编码方式ACCEPT_LANGUAGE表明客户机可接受语言的ISO代码AUTORIZATION表明被证实了的用户FORM列出客户机的EMAIL地址IF_MODIFIED_SINGCE当用get方式请求并且只有当文档比指定日期更早时才返回数据PRAGMA设定将来要用到的服务器代理REFFERER指出连接到当前文档的文档的URLUSER_AGENT客户端浏览器的信息CONTENT_TYPE:如application/x-,表示数据来自HTML表单,并且经过了URL编码。ACCEPT:客户机所支持的MIME类型清单,内容如:”image/gif,image/jpeg”REQUEST_METHOD:它的值一般包括两种:POST和GET,但我们写CGI程序时,最后还要考虑其他的情况。1.POST方法如果采用POST方法,那么客户端来的用户数据将存放在CGI进程的标准输入中,同时将用户数据的长度赋予环境变量中的CONTENT_LENGTH。客户端用POST方式发送数据有一个相应的MIME类型(通用Internet邮件扩充服务:Multi-purposeInternetMailExtensions)。目前,MIME类型一般是:application/x-,该类型表示数据来自HTML表单。该类型记录在环境变量CONTENT_TYPE中,CGI程序应该检查该变量的值。2.GET方法在该方法下,CGI程序无法直接从服务器的标准输入中获取数据,因为服务器把它从标准输入接收到得数据编码到环境变量QUERY_STRING(或PATH_INFO)。GET与POST的区别:采用GET方法提交HTML表单数据的时候,客户机将把这些数据附加到由ACTION标记命名的URL的末尾,用一个包括把经过URL编码后的信息与CGI程序的名字分开:?name=hgq$id=1,QUERY_STRING的值为name=hgq&id=1有些程序员不愿意采用GET方法,因为在他们看来,把动态信息附加在URL的末尾有违URL的出发点:URL作为一种标准用语,一般是用作网络资源的唯一定位标示。环境变量是一个保存用户信息的内存区。当客户端的用户通过浏览器发出CGI请求时,服务器就寻找本地的相应CGI程序并执行它。在执行CGI程序的同时,服务器把该用户的信息保存到环境变量里。接下来,CGI程序的执行流程是这样的:查询与该CGI程序进程相应的环境变量:第一步是request_method,如果是POST,就从环境变量的len,然后到该进程相应的标准输入取出len长的数据。如果是GET,则用户数据就在环境变量的QUERY_STRING里。3.POST与GET的区别以GET方式接收的数据是有长度限制,而用POST方式接收的数据是没有长度限制的。并且,以GET方式发送数据,可以通过URL的形式来发送,但POST方式发送的数据必须要通过Form才到发送。三.CGI程序实现步骤1.从服务器获取数据C语言实现代码:#includestdio.h#includestdlib.h#includestring.hintget_inputs(){intlength;char*method;char*inputstring;method=getenv(“REQUEST_METHOD”);//将返回结果赋予指针if(method==NULL)return1;//找不到环境变量REQUEST_METHODif(!strcmp(method,”POST”))//POST方法{length=atoi(getenv(“CONTENT_LENGTH”));//结果是字符,需要转换if(length!=0){inputstring=malloc(sizeof(char)*length+1)//必须申请缓存,因为stdin是不带缓存的。fread(inputstring,sizeof(char),length,stdin);//从标准输入读取一定数据}}elseif(!strcmp(method,“GET”)){Inputstring=getenv(“QUERY_STRING”);length=strlen(inputstring);}if(length==0)return0;}Perl实现代码:$method=$ENV{‘REQUEST_METHOD’};if($methodeq‘POST’){Read(STDIN,$input,$ENV{‘CONTENT_LENGTH’});}if($methodeq‘GET’||$methodeq‘HEAD’){$input=$ENV{‘QUERY_STRING’};}if($inputeq“”){&print_form;exit;}PYTHON代码实现#!/usr/local/bin/pythonimportcgidefmain():form=cgi.FieldStorage()Python代码实现更简单,cgi.FieldStorage()返回一个字典,字典的每一个key就是变量名,key对应的值就是变量名的值,更本无需用户再去进行数据解码!获取环境变量的时候,如果先判断“REQUEST_METHOD”是否存在,程序会更健壮,否则在某些情况下可能会造成程序崩溃。因为假若CGI程序不是由服务器调用的,那么环境变量集里就没有与CGI相关的环境变量(如REQUEST_METHOD,REMOTE_ADDR等)添加进来,也就是说“getenv(“REQUEST_METHOD”)”将返回NULL!2.URL编码不管是POST还是GET方式,客户端浏览器发送给服务器的数据都不是原始的用户数据,而是经过URL编码的。此时,CGI的环境变量Content_type将被设置,如Content_type=application/x-表单变量数据。编码的基本规则是:变量之间用“&”分开;变量与其对应值用“=”连接;空格用“+”代替;保留的控制字符则用“%”连接对应的16禁止ASCII码代替;某些具有特殊意义的字符也用“%”接对应的16进制ASCII码代替;空格是非法字符;任意不可打印的ASCII控制字符均为非法字符。例如,假设3个HTML表单变量filename、e-mail和comments,它们的值对应分别为hello、mike@hotmail.com和I’llbethereforyou,则经过URL编码后应为:filename=hello&e-mail=hello@hotmail.com&comments=I%27ll+be+there+for+you所以,CGI程序从标准输入或环境变量中获取客户端数据后,还需要进行解码。解码的过程就是URL编码的逆变:根据“&”和“=”分离HTML表单变量,以及特殊字符的替换。在解码方面,PYTHON代码实现是最理想的,cgi.FieldStorage()函数在获取数据的同时就已自动进行代码转换了,无需程序员再进行额外的代码编写。Perl其次,因为在一个现成的Perl库:cgi-lib.pl中提供了ReadParse函数,用它来进行URL解码很简单:require‘cgi-lib.pl’;&ReadParse(*input);3.CGI数据输出CGI程序如何将信息处理结果返回给客户端?这实际上是CGI格式化输出。在CGI程序中的标准输出stdout是经过重定义了的,它并没有在服务器上产生任何的输出内容,而是被重定向到客户浏览器,这与它是由C,还是Perl或Python实现无关。所以,我们可以用打印来实现客户端新的HTML页面的生成。比如,C的printf是向该进程的标准输出发送数据,Perl和Python用print向该进程的标准输出发送数据。(1)CGI标题CGI的格式输出内容必须组织成标题/内容的形式。CGI标准规定了CGI程序可以使用的三个HTTP标题。标题必须占据第一行输出!而且必须随后带有一个空行。标题描述Content_type(内容类型)设定随后输出数据所用的MIME类型Location(地址)设定输出为另外一个文档(URL)Status(状态)指定HTTP状态码MIME:向标准输出发送网页内容时要遵守MIME格式规则:任意输出前面必须有一个用于定义MIME类型的输出内容(Content-type)行,而且随后还必须跟一个空行。如果遗漏了这一条,服务将会返回一个错误信息。(同样使用于其他标题)例如Perl和Python:print“Content-type:text/html\n\n”;//输出HTML格式的数据print“bodywelcomebr”print“/body”C语言:printf(“Content-type:text/html\n\n”);printf(“Welcome\n”);MIME类型以类型/子类型(type/subtype)的形式表示。其中type表示一下几种典型

1 / 11
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功