. Web 最初目的是在全球范围内对文档进行在线存储和归档(大多用于教学和科研)。这些文件通常用静态文本表示,一般是 HTML。随着因特网和 Web 服务的发展,除了浏览之外,还需要处理用户的输入。
现在服务器的处理过程一般是:第一步Web服务器从客户端接受到请求(GET或POST),并调用相应的程序;然后等待HTML页面,与此同时客户端也在等待;当应用程序处理完成,会将动态生成的HTML页面返回服务器端;然后服务器再将这个结果返回给用户。
创建 HTML 的 CGI 应用程序通常是用高级编程语言来实现的,可以接受、处理用户数据,向服务器端返回 HTML 页面。在接触 CGI 之前,需要告诫的是,一般生产环境的 Web应用都不再使用 CGI 了。 如今 Web 服务器典型的部件有 Apache 和集成的数据库访问部件(MySQL 或者 PostgreSQL)、Java(Tomcat)、PHP和各种动态语言(如 Python 或 Ruby)模块,以及 SSL/security。
. CGI 应用程序和典型的应用程序有些不同,主要的区别在于输入、输出以及用户和程序交互方面。
CGI应用程序的输入是从Web 客户端获得的用户提供的表单数据,而不是从服务器或者硬盘上获得;
CGI应用程序的输出将会发送回连接的 Web 客户端,而不是发送到屏幕、GUI窗口或者硬盘上。这些返回的数据必须是具有一系列有效头文件的 HTML 标签数据;
CGI应用程序中,用户与脚本之间没有任何交互。所有的交互都将发生在 Web 客户端(基于用户的行为)、Web 服务器端和 CGI 应用程序间。
. cgi 模块中有个主要类:FieldStorage 类,其完成了所有的工作。Python CGI脚本启动的时候实例化这个类,实例化完成后,其中会包含一个类似字典的对象,它具有一系列键值对,键是通过表单传入的表单条目的名字,值则包含相应的数据。
这些值可以是以下三种对象之一:
1.FieldStorage对象;
2.另一个名为MiniFieldStorage 类的类似实例,用在没有文件上传或 mulitple-part 格式数据的情况下;
3.它们还可以是这些对象的列表。当表单中的某个字段有多个输入值时就会产生这种对象。
. Web 服务器在收到无法理解的响应时,会抛弃这个响应,返回“500 错误”。500 是一个HTTP 响应编码,它表示发生了一个内部服务器错误。一般是服务器所执行的应用程序发生了错误。此时在浏览器中给出的提示消息没什么用,要么是空白,要么显示“内部服务器错误”或类似消息。
当 Python 程序在命令行或集成开发环境(IDE)中运行时,发生的错误会生成回溯消息,指出错误发生的位置,在浏览器中不会显示回溯消息。若想在浏览器中看到的是 Web 应用程序的回溯信息,而不是“内部服务器错误”,可以使用 cgitb 模块。其使用方法只需要将下面代码插入CGI程序中并调用:
import cgitb
cgitb.enable()
. 为了用 Python 进行 CGI 开发,首先需要安装一个 Web 服务器,将其配置成可以处理Python CGI 请求,然后让 Web 服务器访问 CGI 脚本。
生产环境中的服务器。如果需要一个真正的 Web 服务器,可以下载并安装 Apache、ligHTTPD 或 thttpd。Apache中有许多插件或模块可以处理 Python CGI;
开发人员服务器。出于学习目的或者想建立小型 Web 站点,使用 Python 自身带的 Web 服务器就已经足够,在Python3中构建步骤如下:
1.在建好的文件夹下打开cmd窗口,进入python命令窗口下输入:
python -m http.server --cgi
. 2.在该文件夹下建立新文件夹,命名为cgi-bin;
3.将python脚本放入该文件夹下,就可以在浏览器中输入:
http://localhost:8000/cgi-bin/xxx.py
来查看。
. 接下来的例子是创建一个静态的页面,获取用户的输入,将交互行为交给后面的python脚本,得到处理结果后在显示出来:
第一步:创建静态页面。在打开端口的文件夹目录下创建friend.html文件如下:
friends CGI demon
Friends list for:NEW user
. 第二步,在cgi-bin目录下创建friends.py脚本:
import cgi
reshtml = '''Content-Type: text/html\n
Friends CGI demon (dynamic)
Friend list for:%s
Your name is: %s
you have %sfriends.
'''
form = cgi.FieldStorage()
who = form['person'].value
howmany = form['howmany'].value
print(reshtml % (who,who,howmany))
. 第三步,在浏览器搜索栏输入:http://localhost:8000/friend.htm
l打开静态页面后,输入相应选项,点击submit按钮,将会调用python脚本生成结果页面。
. 接下来的例子将html文件舍弃,表单页和结果都有python脚本生成:
import cgi
header = 'Content-Type: text/html\n\n'
formhtml = '''
Friends CGI demon
Friends list for :new user
'''
fradio = '%s\n'
def showForm():
friends = []
for i in (0,10,20,30,40):
checked = ''
if i == 0:
checked = 'CHECKED'
friends.append(fradio % (str(i),checked,str(i)))
print('%s%s' % (header,formhtml % ''.join(friends))) #join函数使得friends中每个元素以''连接
reshtml = '''
Friends CGI demon
Friends list for:%s
your name is: %s
you have %s friends.
'''
def doresult(who,howmany):
print(header + reshtml % (who,who,howmany))
def process():
form = cgi.FieldStorage()
if 'person' in form:
who = form['person'].value
else:
who = 'new user'
if 'howmany' in form:
howmany = form['howmany'].value
else:
howmany = 0
if 'action' in form:
doresult(who,howmany)
else:
showForm()
if __name__ == '__main__':
process()
. 最后的例子对代码做了更多的完善,只是逻辑上的,没有新知识:
import cgi
import urllib
header = 'Content-Type: text/html\n\n'
url = "/cgi-bin/friendsc.py"
errhtml = '''html>
Friends CGI demon
Error
%s