Format |
Content-Type |
HTML | text/html |
Text | text/plain |
GIF | image/gif |
JPEG | image/jpeg |
PostScript | application/postscript |
MPEG | video/mpeg |
图4. 脚本的结果
这是个很简单的例子, 他能这样备调用:
A HREF="http://www.popchina.com/cgi-bin/pinglaura">Is Laura Logged in?/A>这是没有输入的脚本,它只运行并且返回数据.
根据前面的阐述,这个脚本内容是这样::
#!/bin/sh
echo Content-type: text/html
echo "HTML>HEAD>"
echo "TITLE>Is Laura There?/TITLE>"
echo "/HEAD>BODY>"
为了测试我是否已经登陆系统,用who命令(我的登陆名假设为lemay), 储存结果在变量ison中. 如果我登陆, 变量ison将有些内容,否则则是空的.
ison='who | grep lemay'试验结果及返回相应提示的脚本是这样:
if [ ! -z "$ison" ]; then echo "P>Laura is logged in."/P> else echo "P>Laura isn't logged in."/P> fi最后关闭HTML:
echo "/BODY>/HTML>"现在你通过从命令行运行他,测试一下,你将得到一个结果说我未登陆你的系统,当然不可能的,他的输出是这样的:
Content-type: text/html HTML>HEAD> TITLE>Are You There?/TITLE> /HEAD>BODY> P>Laura is not logged in. /BODY>/HTML>这是输出的一个HTML文本,这样你的浏览器能正常显示他,因为他是个HTML文件。
这个例子完整的脚本如下:
#!/bin/sh echo "Content-type: text/html" echo echo "HTML>HEAD>" echo "TITLE>Is Laura There?/TITLE>" echo "/HEAD>BODY>" ison='who | grep lemay' if [ ! -z "$ison" ]; then echo "P>Laura is logged in" else echo "P>Laura isn't logged in" fi echo "/BODY>/HTML>"
A HREF="/cgi-bin/myscript?arg1+arg2+arg3">run my script/A>当服务器接收到这个请求,它传递 arg1, arg2, 和 arg3 参数给脚本. 你然后能在脚本中使用这些参数.
这个方法有时叫查询, 因为早期它用在搜索功能中.
我们取个不同题目:
#!/bin/sh echo "Content-type: text/html" echo echo "HTML>HEAD>" echo "TITLE>Are You There?/TITLE>" echo "/HEAD>BODY>"在上面的例子中, 下一步应该是测试我是否登陆,在这里我们用参数${1}代替我的名字lemay, ${1}作为第一个参数, ${2}作为第二个, ${3}作为第三个.
ison='who | grep "${1}"'
剩下的所有修改如下:
if [ ! -z "$ison" ]; then echo "P>$1 is logged in" else echo "P>$1 isn't logged in" fi
echo "/BODY>/HTML>"好了,让我们修改HTML页中的连接吧!原来是这样:
A HREF="http://www.lne.com/cgi-bin/pinglaura">Is Laura Logged in?/A>修改为通用查询功能后是这样,比如查询名字叫john的人是否登陆:
A HREF="http://www.lne.com/cgi-bin/pinggeneric?john">Is John Logged in?/A>在你的服务器上试试,看是否有结果。
看下面一个路径信息path information例子, :
http://myhost/cgi-bin/myscript/remaining_path_info?arg1+arg2当脚本运行时,在路径中的信息将被放置于环境参数PATH_INFO. 你能在你的脚本内容中使用这些信息.
比如说, 让我们假设你在多页上已有多个连接到同一个脚本. 你能用这个路径信息显示那个有连接的HTML文件名. 这样, 在你完成处理你的脚本之后, 当你发回一个HTML文件时, 你能在这个文件里包含一个连接,发回用户一开始那个页。
你会在下一章节学到更多路径信息:有用的表单和脚本. 待后来登出
不用怕, 这里开始解释这些情况.
Location: ../docs/final.html这个Location行用作通常的输出位置,也就是说,如果你用了Location, 你就不必再用象Content-type这样的数据输出(实际上,你也不能). 正如Content-type, 你也必须在这一行后面跟一个空行.
指向这个文件的路径可以是一个URL或相对路径. 所有相对路径是指相对于脚本所在的位置. 例子中的final.html文本是在当前上一个目录下docs的目录下:
echo Location: ../docs/final.html echo
很幸运, 这一切很容易. 你只要输出下面这个命令即可(后面跟一个空行):
echo Status: 204 No Response echo这个Status头部提供状态码给服务器(并且也给浏览器). 特别的204将传递给浏览器,如果能识别它,它将什么也不做.
记住, 大多数表单有两个部分: HTML的表单格式;处理表单数据的CGI脚本. 这个CGI脚本使用标签FORM>属性调用的.
这个ACTION属性包含着处理表单的脚本:
FORM ACTION="http://www.popchina.com/cgi-bin/processorscript">在这个表单中, 每个输入区都有一个NAME的属性, 用来称呼表单元素. 当这个表单数据被递交给你在ACTION中定义的CGI脚本, 这样这些name和输入内容被作为一个数字或字符传递给脚本.
我们上面谈论的方法,实际是GET,它将数据打包放置在环境变量QUERY_STRING中作为URL整体的一部分传递给服务器。
POST做很多类似GET同样的事情, 不同的地方就是它是分离地传递数据给脚本. 你的脚本通过标准输入获取这些数据. (有些Web服务器是存储在临时文件中.) 这个QUERY_STRING环境变量将不再设置.
那你用那个方法呢? POST是个安全的方法, 尤其如果你的表单中有很多数据的话. 当你用GET, 这个服务器就分配变量QUERY_STRING给所有的表单数据, 但是这个变量可存储量是有限的. 换句话说,如果你有很多数据但是你又用GET,你会丢失很多数据.
如果你用POST, 你可以尽可能多地使用数据, 因为这些数据从来也不分配到一个变量里.
theName=Ichabod+Cranegender=malestatus=missingheadless=yesURL编码遵循下列规则:
这里介绍一个叫uncgi的解码程序, 你可以从http://www.hyperion.com/~koreth/uncgi.html. 得到原码,安装在你自己的cgi-bin目录下.
图5. 告诉我你的名字的表单.
这个输入被发给脚本, 然后发回显示一个hello的信息(间图.6).
如果你在姓名输入处不输入任何东东,会怎样?见图7.
图6. 姓名表单的结果.
图7. 另一个结果.
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可以工作得很好.
在脚本中第一步是解码,在这个例子中, 我们已经使用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-bin目录中吗?如果你的服务器允许带.cgi扩展名的CGI运行, 你的脚本文件名的扩展名是这样吗?
解答还是如上一条一样,然后你用命令行执行你的CGI,可以正常运行吗?是否有错误?.
确定你的头部行和数据部之间有一空行.
确定你的脚本是可执行的(在UNIX, 用chmod +x 你的脚本.cgi). 在从浏览器运行之前,你应当从命令行运行你的脚本,如果客户端是win95,可以用telnet登陆你的服务器,执行命令行,当然必须了解UNIX命令.
环境变量 |
意义 |
SERVER_NAME | CGI脚本运行时的主机名和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_METHOD | POST 或 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递交的表单, 标准输入口的字节数. |
当然也有表单上载时可以解码的程序,很少。
为了使用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 .
注意:上述程序可以用ultra edit来编辑,注意转换UNIX格式 ,必须采用UNIX格式存盘,再上载,用telnet登陆,在命令行键入perl sample.pl,看有无bug,再 在浏览器中调用。CGI程序包括放置CGI的目录一定要改属性为777, 要写入的HTML文件也要改属性为777.
现在网上有很多免费的cgi,基本可以满足一般需求,请到这个网址查询你要的cgi:http://www.itm.com/cgicollection/
本人汉化了一个古老的通用留言簿,大家可以拿去做自己的留言簿。这里下载