Python CGI学习与测试

一、 简介

公共网关接口(Common Gateway Interface,CGI)是Web 服务器运行时外部程序的规范,按CGI 编写的程序可以扩展服务器功能。CGI 应用程序能与浏览器进行交互,还可通过数据API与数据库服务器等外部数据源进行通信,从数据库服务器中获取数据。格式化为HTML文档后,发送给浏览器,也可以将从浏览器获得的数据放到数据库中。几乎所有服务器都支持CGI,可用任何语言编写CGI,包括流行的C、C ++、Java、VB 和Delphi 等。顺便说说WSGI,这个只是个规范,不是API也不是代码。
注:在测试的时候,可以预先写一个html文字段,把你不知道的字段放进去输出到网页(str()),这样可以快速定位错误

二、 启动服务器

运行该服务器只需几行代码:

# coding=utf-8
from http.server import CGIHTTPRequestHandler, test
test(CGIHTTPRequestHandler)

其默认的端口为8000,运行时可以指定端口,代码如下:

python3 cgidemo.py 8080

三、简单表单示例

文件结构:

  • cgidemo.py 服务器开启文件
  • friend.html 表单页面
  • cgi-bin/ 脚本文件夹
  • cgi-bin/friend.py 处理表单的脚本文件

代码如下:

friend.html
<html>
    <body>
      <title>Friends!hello!</title>
      <form action="/cgi-bin/friend.py">
        <p>please input your name</p>
        <input type="text" name="person" id="1" value="NER USER">
        <p>How many friend do you have</p>
        <input type="radio" name="howmany" value="0" checked="True">0
        <input type="radio" name="howmany" value="10" >10
        <input type="radio" name="howmany" value="25" >25
        <input type="radio" name="howmany" value="50" >50
        <input type="radio" name="howmany" value="10" >100
        <input type="submit">
      </form>

    </body>
</html>
cgi-bin/friend.py
# coding=utf-8
reshtml = '''
<html><head><title>
friend CGI Demo
</title></head>
<body><h3>Friend list for<i>%s</i></h3>
Your name is: <b>%s</b><p>You have <b>%s</b> friends.
</body></html>
'''
form = cgi.FieldStorage()	//表单存储类实例化
who = form['person'].value	
howmany = form['howmany'].value
print(reshtml%(who, who, howmany))

四、 高级CGI(上传,cookie)

注:CGI只支持两种表单提交和文件上传方式:1.mulitipart(上传文件专用) 2.application/x-www-form-urlencoded(默认)

cookie的设置:

cookie的设置很简单,只需要把cookie的值放在html中即可,如:

Content-Type: text/html
Set-Cookie: name="MYCGI";expires=Wed, 28 Aug 2016 18:30:00 GMT
···

其cookie保存在os.environ[‘HTTP_COOKIE’]中
其语法如下:

Set-cookie:name=name;expires=date;path=path;domain=domain;secure

  • name=name: 需要设置cookie的值(name不能使用";“和”,"号),有多个name值时用 “;” 分隔,例如:name1=name1;name2=name2;name3=name3。
  • expires=date: cookie的有效期限,格式: expires=“Wdy,DD-Mon-YYYY HH : MM : SS”
  • path=path: 设置cookie支持的路径,如果path是一个路径,则cookie对这个目录下的所有文件及子目录生效,例如: path="/cgi-bin/",如果path是一个文件,则cookie指对这个文件生效,例如:path="/cgi-bin/cookie.cgi"。
  • domain=domain: 对cookie生效的域名,例如:domain=“www.baidu.com”
  • secure: 如果给出此标志,表示cookie只能通过SSL协议的https服务器来传递。
  • cookie的接收是通过设置环境变量HTTP_COOKIE来实现的,CGI程序可以通过检索该变量获取cookie信息。
文件上传

上面已经说过文件上传的方式,这里强调,必须用post方式上传!否则读不到内容!
上传之后通过file.filename.value取其文件名,通过file.file.read()取文件内容。

粗糙的测试代码如下(半成品,还有展示错误页面,展示cookie等功能没完成):

#coding=utf-8

#this file is to show the use of cookie
from cgi import FieldStorage
from os import *
from io import StringIO
# from urllib import quote, unquote

class demoCGI:
    header = 'Content-type:text/html \n'
    # the script for dealing with data
    url='/cgi-bin/friendB.py'

    # the html 1:action 2:CPPusercookie 3:setcookitcalue 4:setname 5:langItem
    formhtml = '''
<html><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><head><title>
friend CGI Demo
</title></head>
<body>
<h2>My Advance CGI Demo</h2>
    <form action="%s" method="post" enctype="multipart/form-data">
      <h3>My cookie Setting</h3>
      <li><b>CPPuser: %s</b></li>
      <h3>Enter Cookie Value: <input name="cookie" value="%s">(<i>optional</i>)</h3>
      <h3>Enter Your   Name : <input name="person" value="%s">(<i>require</i>)</h3>      
      <h3>What language can you program in?(<i>At least one require!</i>)<br>%s</h3>
      <h3>Upload the   File : <input name="upfile" type="file" size=45>(<i><small>Max size:4K</small></i>)</h3>      
      <p><input type='submit'></p>
    </form>
</body></html>'''


    reshtml = '''
<html><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><head><title>
friend CGI Demo
</title></head>
<body>
<h2>You Upload the file!</h2>
<h3>Your cookie's value: %s</h3>
<h3>Your name: %s</h3>
<h3>Your language: </h3> %s
<h2>You had uploaded the file, and its name is: %s</h2>
<h3>The file's content: </h3>
%s
</body></html>'''


    # the set of language and the text of checkbox
    langSet = ('Python', 'Java', 'PHP', 'C++', 'Javascript', 'Go', 'Ruby')
    # the first %s is for the language name and the second is for whether this language is checked or not
    langItemText = "<input type='checkbox' name='lang' value='%s' %s> %s"

    def buildItem(self, langSet,langItemText):
        res = ""
        check = "checked"
        for lang in langSet:
            res += langItemText % (lang, check, lang)
            if check == "checked":
                check = ""
        return res

    # to run the proc
    def go(self):
        # cookie store only cookie but the name
        self.cookie = {}
        self.error = ''
        form = FieldStorage()
        if not form.keys():
            cookieerror = 'You have no cookie!'
            cookievalue = 'Hey! Input the cookie!'
            namevalue = 'Hey! Input your name!'
            langhtml = self.buildItem(self.langSet, self.langItemText)
            print("%s%s" % (self.header, self.formhtml % (self.url, cookieerror, cookievalue, namevalue, langhtml)))
            return

        if 'cookie' in form:
            self.cookie['cookie'] = form['cookie'].value

        if 'person' in form:
            self.person = form['person'].value
        else :
            self.error = 'Your name is required!'

        if 'lang' in form:
            langData = form['lang']
            # 判断是否类型相同
            if isinstance(langData, list):
                self.langs = [eachlang.value for eachlang in langData]
            else:
                self.langs = [langData.value]
        else:
            self.error = "At least one language required!"
        self.file = ""
        if 'upfile' in form:
            upfile = form['upfile']
            # Upfile or not
            self.fn = upfile.value
            self.file = str(upfile.file.read(4096))

        if self.error == '':
            self.doResult()
        else:
            self.go()

    # read Cookie form client
    def getCPPcookie(self):
        if 'HTTP_COOKIE' in environ:
            print(environ['HTTP_COOKIE'])

    def setCPPcookie(self):
        if self.cookie:
            tmpcookie = "cookie=" + self.cookie['cookie']
            return "Set-Cookie: %s"%(tmpcookie)


    def doResult(self):

        # cookie
        cookieItem = self.setCPPcookie()

        # name
        personItem = self.person

        # language item
        langItem = "<ul>"
        for eachlang in self.langs:
            langItem += '<li>' + eachlang + '</li>'
        langItem += '</ul>'

        # file
        print ('Content-Type: text/html')
        print (cookieItem)
        print(self.reshtml%(self.cookie['cookie'],personItem,langItem,self.fn,self.file))



if __name__ == '__main__':
   page = demoCGI()
   page.go()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值