python 编写 cgi 脚本

cgi.py

使用python编写cgi程序时,需要使用该模块;它还提供了一些调试脚本,以及处理文件上传请求的工具。

1 介绍

cgi脚本由http server(Apache httpd,nginx)调用,通常处理一些用户提交的信息。

CGI脚本的输出应该包括两部分,这两部分由空行分开。

第一部分说明返回内容的形式:

print "Content-Type: text/html"     # HTML is following
print                               # blank line, end of headers

第二部分是返回的内容,一般为html;

print "<TITLE>CGI script output</TITLE>"
print "<H1>This is my first CGI script</H1>"
print "Hello, world!"

2 使用

2.1

模块引用

import cgi
import cgitb
cgitb.enable()

cgitb 会开启异常处理机制,可以在浏览器中看到错误的详细信息。如果不想在页面显示,也可以通过以下形式将其保存在指定文件中:

import cgitb
cgitb.enable(display=0, logdir="/path/to/logdir")

在开发cgi脚本时特别有用。可以在脚本测试完成后,再删除cgitb配置行。

2.2 表单数据

处理表单数据时,最好使用 FieldStorage 类。

form = cgi.FieldStorage()
if "name" not in form or "addr" not in form:
    print "<H1>Error</H1>"
    print "Please fill in the name and addr fields."
    return
print "<p>name:", form["name"].value
print "<p>addr:", form["addr"].value
...further form processing here...

值为空的表单字段会被过滤掉,因此使用时需要判断是否存某字段,也可以使用FieldStorage(keep_blank_values=true)来保留这些空值的字段。

  1. 字段值可以通过value属性获得;
  2. 也可以通过getvalue()方法获得,getvalue()方法运行设置defalut value。

当提交的表单中,一个字段name对应多个value时, getvalue()将返回一个list。如果使用 form.getlist(),那么将始终返回一个list。

value = form.getlist("username")
usernames = ",".join(value)

表单:

<input type="checkbox" name="item" value="1" />
<input type="checkbox" name="item" value="2" />

cgi脚本可以这样写:

item = form.getvalue("item")
if isinstance(item, list):
    # The user is requesting more than one item.
else:
    # The user is requesting only one item.

如果以简单的形式处理:

user = form.getvalue("user").upper()

这种情况下,请求数据的格式一定不能出错,如果有的client在url的query字符串中也添加了一个 item=foo。那么cgi脚本就崩溃了,因为getvalue会返回一个列表。

这种通过判断的形式写的cgi脚本,逻辑判断太多,可读性不好。一个更方便的方法是使用 getfirst() 和 getlist()。

FieldStorage.getfirst(name [, defalut])

该方法只返回第一个值,当然第一值是否与期望值是否匹配,因浏览器而异。如果字段值为空时,也可以给定一个默认值。

FieldStorage.getlist(name)

该方法始终返回一个list,当值为空时,则返回空list。

import cgi
form = cgi.FieldStorage()
user = form.getfirst("user", "").upper()    # This way it's safe.
for item in form.getlist("item"):
    do_something(item)

这样的代码会显得更加优雅紧凑。

2.3 上传文件处理

如果字段为上传的文件名,那么通过value或者getvalue()访问该时将会以字符串的形式读取内存中的文件。一般情况下,应该先做判断,然后再读取。

fileitem = form["userfile"]
if fileitem.file:
    # It's an uploaded file; count lines
    linecount = 0
    while 1:
        line = fileitem.file.readline()
        if not line: break
        linecount = linecount + 1

通过Post提交的表单,同时又存在 query 字符串的形式,那么将同时包含 FieldStorage 和 MiniFieldStorage。

3 函数

cgi.parse()
cgi.parse_header()
cgi.test()
cgi.print_environ()
cgi.print_form()
cgi.print_directory()
cgi.print_environ_usage()
cgi.escape()

4 其他

  1. 对于任何需要cgi脚本读、写的文件,应该有足够的读(0644)写(0666)权限,出于安全考虑,HTTP server以 ‘nobody’用户执行脚本,没有任何特殊权限。

  2. 当需要加载自定义的 python 模块时,可以先在脚本中更改模块搜索路径。

import sys
sys.path.insert(0, "/usr/home/joe/lib/python")
sys.path.insert(0, "/usr/local/lib/python")
  1. 如果脚本有语法错误,Pyhotn解析器就不会去执行,HTTP Server将会发送未知错误到client。
#> python cgi-script.py 

通过以上方式可以检测是否有语法错误。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值