了解CGI(二)

本文深入探讨了Web开发中GET和POST两种表单提交方式的区别与应用场景。GET将数据附在URL后传递,适用于数据量小的情况;POST则通过请求体发送数据,适合大数据量传输。文章还介绍了URL编码规则及如何利用CGI脚本处理表单数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GET 和 POST

表单从浏览器发给服务器有两种方法.  GET 和 POST.

我们上面谈论的方法,实际是GET,它将数据打包放置在环境变量QUERY_STRING中作为URL整体的一部分传递给服务器。

POST做很多类似GET同样的事情, 不同的地方就是它是分离地传递数据给脚本. 你的脚本通过标准输入获取这些数据. (有些Web服务器是存储在临时文件中.) 这个QUERY_STRING环境变量将不再设置.

那你用那个方法呢? POST是个安全的方法, 尤其如果你的表单中有很多数据的话. 当你用GET, 这个服务器就分配变量QUERY_STRING给所有的表单数据, 但是这个变量可存储量是有限的. 换句话说,如果你有很多数据但是你又用GET,你会丢失很多数据.

 

如果你用POST, 你可以尽可能多地使用数据, 因为这些数据从来也不分配到一个变量里.

 

URL 编码

URL 编码是一种浏览器用来打包表单输入的格式. 浏览器从表单中获取所有的name和其中的值 ,将他们作为name/value参数编码, 移去那些不能传送的字符, 将数据排行等等,这些还取决于你用GET还是POST?作为URL的一部分或者分离地发给服务器. 不管哪种情况, 在服务器端的表单输入格式样子象这样:

theName=Ichabod+Crane&gender=male&status=missing&headless=yes

URL编码遵循下列规则:

  • 每对name/value由&符分开.
  • 每对来自表单的name/value由=符分开. 如果用户没有输入值给这个name,那么这个name还是出现,只是无值(象这样 "name=").
  • 任何特殊的字符(就是那些不是简单的七位ASCII,如汉字) 将以百分符%用十六进制编码. 当然也包括象 =, &, 和 % 这些特殊的字符.
  • 在输入区中的空格将以加号+显示.

因为表单输入是用这个URL编码传递给你的脚本的,在你用这些参数之前必须解码,因为解码是个很普遍的工作,可以有很多工具做这个工作 . 你没有必要自己写这个解码程序.

 

这里介绍一个叫uncgi的解码程序, 你可以从 http://www.hyperion.com/~koreth/uncgi.html. 得到原码,安装在你自己的cgi-bin目录下.

 

练习3: 告诉我你的名字.

让我们以这个例子来说明,如图5.

 了解CGI(二)

这个输入被发给脚本, 然后发回显示一个hello的信息(见图.6).

 了解CGI(二)

如果你在姓名输入处不输入任何东东,会怎样?见图7.

 

修改表单的HTML

现在我们举一个真实的例子:

<FORM METHOD=POST ACTION="../cgi-bin/form-name">


</FORM>

如果你在用uncgi从input中解码, 情况有点不同. 为了是uncgi正常工作, 你首先必须调用uncgi , 如果uncgi是个目录,加上实际的脚本名, 象这样:

<FORM METHOD=POST ACTION="../cgi-bin/uncgi/form-name">


</FORM>
这样,你不必修改表单中原始的HTML; 原始的HTML可以工作得很好.
脚本

处理表单输入的是个CGI脚本, 让我们来仔细地看看。

在脚本中第一步是解码,在这个例子中, 我们已经使用uncgi解码输入数据, 实际这个表单已经为你做好解码. 通过建立一个uncgi的目录,一旦表单递交给服务器,服务器会自动进行解码,这样,所有的name/value已经准备就绪等待你的使用.

现在,一个例子开始部分假设是下面这样:

echo Content-type: text/html


echo


echo "<HTML><HEAD>"


echo "<TITLE>Hello</TITLE>"


echo "</HEAD><BODY>"


echo "<P>"

接下来,有两种情况要处理:一件是处理用户不输入名字的情况,一个是如果输入了向他们说hello.

这个Name元素的值, 是包含在WWW_theName环境变量中. 用一个简单的测试命令(-z), 你能查看环境变量是否是空的还是包括相应的输出值:

if [ ! -z "$WWW_theName" ]; then


    echo "Hello, "


    echo $WWW_theName


else


    echo "You don't have a name?"


fi

最后增加一个连接"go back" . 用来返回:

echo "</P><P><A HREF="../lemay/name1.html">Go Back</A></P>"


echo "</BODY></HTML>"

问题

这里是使用CGI脚本比较普遍的问题:

  • 脚本内容只显示不执行.


    你正确配置了你的服务器运行CGI脚本? 你的脚本是放置在cgi-bin目录中吗?如果你的服务器允许带.cgi扩展名的CGI运行, 你的脚本文件名的扩展名是这样吗?

  • Error 500: Server doesn't support POST.


    解答还是如上一条一样,然后你用命令行执行你的CGI,可以正常运行吗?是否有错误?.

  • Document contains no data.


    确定你的头部行和数据部之间有一空行.

  • Error 500: Bad Script Request.


    确定你的脚本是可执行的(在UNIX, 用chmod +x 你的脚本.cgi). 在从浏览器运行之前,你应当从命令行运行你的脚本,如果客户端是win95,可以用telnet登陆你的服务器,执行命令行,当然必须了解UNIX命令.

CGI变量

表2 总结那些环境变量.

表2. CGI 环境变量.


 

环境变量         
意义
SERVER_NAMECGI脚本运行时的主机名和IP地址.
SERVER_SOFTWARE你的服务器的类型如: CERN/3.0 或 NCSA/1.3.
GATEWAY_INTERFACE运行的CGI版本. 对于UNIX服务器, 这是CGI/1.1.
SERVER_PROTOCOL服务器运行的HTTP协议. 这里当是HTTP/1.0.
SERVER_PORT服务器运行的TCP口,通常Web服务器是80.
REQUEST_METHODPOST 或 GET, 取决于你的表单是怎样递交的.
HTTP_ACCEPT 浏览器能直接接收的Content-types, 可以有HTTP Accept header定义.
HTTP_USER_AGENT递交表单的浏览器的名称、版本 和其他平台性的附加信息。
HTTP_REFERER递交表单的文本的 URL,不是所有的浏览器都发出这个信息,不要依赖它
PATH_INFO附加的路径信息, 由浏览器通过GET方法发出.
PATH_TRANSLATED在PATH_INFO中系统规定的路径信息.
SCRIPT_NAME指向这个CGI脚本的路径, 是在URL中显示的(如, /cgi-bin/thescript).
QUERY_STRING脚本参数或者表单输入项(如果是用GET递交). QUERY_STRING 包含URL中问号后面的参数.
REMOTE_HOST递交脚本的主机名,这个值不能被设置.
REMOTE_ADDR递交脚本的主机IP地址.
REMOTE_USER递交脚本的用户名. 如果服务器的authentication被激活,这个值可以设置。
REMOTE_IDENT如果Web服务器是在ident (一种确认用户连接你的协议)运行, 递交表单的系统也在运行ident, 这个变量就含有ident返回值.
CONTENT_TYPE如果表单是用POST递交, 这个值将是 application/x-www-form-urlencoded. 在上载文件的表单中, content-type 是个 multipart/form-data.
CONTENT_LENGTH对于用POST递交的表单, 标准输入口的字节数.

 

表单输入的解码程序

目前有两个程序: 通用目的的uncgi, 和cgi-lib.pl, 这是个Perl库,用于perl编写的CGI脚本.

 

当然也有表单上载时可以解码的程序,很少。

 

uncgi
说明原码可以从 http://www.hyperion.com/~koreth/uncgi.html获得。
cgi-lib.pl

这是由Steve Brenner编写的, 帮助你管理输入. 他能从GET和POST获取输入并且放置在一个Perl列表或阵列中. 更新的版本也能处理来自表单的文件上传. 从这儿可以得到信息与原码 http://www.bio.cam.ac.uk/cgi-lib. 如果你决定用Perl语言处理你的表单输入,cgi-lib是个很好的库.

为了使用cgi-lib.pl,你通常要这样写:
#!/usr/lib/perl

require 'cgi-lib.pl';

cgi-lib中尽管有很多子程序, 最重要的是ReadParse子程. ReadParse 读取输入方便地将name/value储存在一个Perl阵列中. 在你的Perl脚本中通常是这样调用的:

&ReadParse(*in);

此例中,阵列名是in, 可以随便取名的.

在表单输入解码后, 你能读取和处理这个name/value,方法是象下面这样:

print $in{'theName'};

这个将显示名字name是theName的值value.

 

如果你有多个用同样名字的name对, cgi-lib.pl用(\0)分隔多个名字. 这样可以正常处理你的脚本.

 

解码上传的文件输入

基于表单的文件上传需要不同的表单输入,有一些程序可以对其进行解码。

cgi-lib.pl 后来版本可以很好支持, 在http://www.bio.cam.ac.uk/cgi-lib/ 了解更多的情况.

 

另一个处理用Perl编写的CGI地址是 http://valine.ncsa.uiuc.edu/cgi_docs.html .

 

自己做
找专门书籍学习吧: ftp://ds.internic.net/rfc/rfc1867.txt.

非解剖的脚本头部

按照本书阐述,大多数情况可以正常操作,在一些情况下不是这样的,你可以翻阅说明书了解。

<ISINDEX> 脚本

为了在CGI中完成讨论组, 我们看看叫<ISINDEX>的搜索. 这是早期在浏览器中用来向服务器发出搜索关键字的办法,参看以前的资料。

总结

CGI脚本, 有时叫服务器端脚本或网关脚本。 在internet上有很多免费资源,你可以搜索下载读懂他们,当然都是英文的,如果你下决心翻译他们(可能更加强理解). 这样一举两得啊.

注意:上述程序可以用ultra edit来编辑,注意转换UNIX格式 ,必须采用UNIX格式存盘,再上载,用telnet登陆,在命令行键入perl sample.pl,看有无bug,再 在浏览器中调用。CGI程序包括放置CGI的目录一定要改属性为777, 要写入的HTML文件也要改属性为777.

现在网上有很多免费的cgi,基本可以满足一般需求,请到这个网址查询你要的cgi:http://www.itm.com/cgicollection/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值