Python研究学习--21--web之CGI和WSGI

版权声明:本文为博主原创文章,转载本站文章请注明作者和出处,请勿用于任何商业用途。 https://blog.csdn.net/wutianxu123/article/details/82560873

17.1 理论基础

CGI工作原理:(通用网关接口)
1、web服务器从客户端接到了请求(即GET或者POST),并调用相应的CGI应用程序。
2、等待HTML页面,与此同时,客户端也在等待。
3、一旦应用程序处理完成,它会将生成的动态HTML页面返回服务器端,然后服务器端再将这个最终结果返回给用户。
需要注意的是,由于CGI有明显的局限性,以及限制Web服务器同时处理客户端的数量,因此一般生产环境的web应用都不再使用CGI了。

CGI应用程序:
与典型应用程序区别在于,输入、输出及用户和计算机交互。所有交互都发生在Web客户端(用户的行为)、Web服务器端和CGI应用程序间。

主要模块:

import cgi
import cgitb

17.2 CGI应用程序

启动最基本的web服务器:

python -m CGIHTTPServer 8000                          #8000是端口号

然后按照如下步骤放置文件:

1、在D:\mypython下新建文件夹cgi-bin,为D:\mypython\cgi-bin
2、在D:\mypython\cgi-bin\下放入.py脚本(结果页面)
3、在D:\mypython\下放入.html文件(表单页面)。该文件与cgi-bin平级
4、浏览器输入<http://localhost:8000/friends.html>打开页面
5、输入搜索内容进行搜索,搜索将调用在D:\mypython\cgi-bin\下的.py脚本

更加简单的方式:

1、抛弃.html文件,将其集成到.py文件中
2、浏览器输入<http://localhost:8000/cgi-bin/friendB.py>打开页面
3、现在该脚本同时生成并控制了表单页面和结果页面

代码实例:

#!/usr/bin/env python
#-*-coding: utf-8-*-
import cgi

header = 'Content-Type: text/html\n\n'
#表单页面变量,包含三个变量action、person和howmany,其中action变量的值在表单页面中是'edit',action变量在这里的作用是作为一个表单页面的标识

formhtml = '''
<HTML>
    <HEAD>
    <meta charset="UTF-8">                            <!--html注释格式!该句为中文标识-->
        <TITLE>这是一个CGI例子</TITLE>
    </HEAD>
    <BODY>
        <H3>
            搜索框如下: <I>输入搜索的内容</I>
        </H3>
        <FORM ACTION="/cgi-bin/friendsB.py">
            <B>你的搜索内容:</B>
            <INPUT TYPE=hidden NAME=action VALUE=edit>
            <INPUT TYPE=text NAME=person VALUE="NEW USER" SIZE=15>
            <P>
                <B>要展示多少搜索结果:</B>%s
            </P>
            <INPUT TYPE=submit>
        </FORM>
    </BODY>
</HTML>'''

fradio = '<INPUT TYPE=radio NAME=howmany VALUE="%s" %s> %s\n'        #创建单选按钮的字符串变量

def showForm():                                       #生成表单页面用于用户输入
    friends = []
    for i in (0, 10, 25, 50, 100):                    #创建单选按钮文字集
        checked = ''
        if i == 0:
            checked = 'CHECKED'
        friends.append(fradio % (str(i), checked, str(i)))

    print '%s%s' % (header, formhtml % ''.join(friends))             #将friend合并到formhtml中

#结果页面变量,只有两个变量person和howmany
reshtml = '''
<HTML>
    <HEAD>
    <meta charset="UTF-8">                             <!--html注释格式!该句为中文标识-->
        <TITLE>这是一个CGI例子</TITLE>
    </HEAD>
    <BODY>
        <H3>
            您搜索的内容如下: <I>%s</I>
        </H3>
        您输入的内容是: <B>%s</B>
        <P>                                            <!--html注释格式!该句为另起一行-->
            您想展示 <B>%s</B> 个结果
        </p>
    </BODY>
</HTML>'''

def doResults(who, howmany):
    print header + reshtml % (who, who, howmany)

def process():
    form = cgi.FieldStorage()                          #读取有关的用户信息,在本例就是action、person和howmany这三个键值对
    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:
        doResults(who, howmany)
    else:                                              #程序第一次运行时,并没有向cgi应用程序提交表单,所以form是不会有action这个键的
        showForm()

if __name__ == '__main__':
    process()

更加完整的例子:页面添加了一个返回链接,使得用户可以从结果页面返回到表单页面,且返回后用户之前输入的信息依然存在。同时添加了一个错误处理页面,如果搜索内容未设置将跳转至错误处理页面进行提示。
注意:与之前的代码段有所不同

#!/usr/bin/env python
#-*-coding: utf-8-*-
import cgi
from urllib import quote_plus                          #新增了库

header = 'Content-Type: text/html\n\n'
url = '/cgi-bin/friendsC.py'                           #单独抽出是因为表单页面和结果页面都会用到

errhtml = '''                                          <!--html注释格式!错误处理页面-->
<HTML>
    <HEAD>
    <meta charset="UTF-8">                             <!--html注释格式!该句为中文标识-->
        <TITLE>这是一个CGI例子</TITLE>
    </HEAD>
    <BODY>
        <H3>错误!</H3>
        <B>%s</B>
        <P>
            <FORM>
                <INPUT TYPE=button VALUE=返回 ONCLICK="window.history.back()">
            </FORM>
        </p>
    </BODY>
</HTML>'''

def showError(error_str):
    print header + errhtml % error_str

formhtml = '''
<HTML>
    <HEAD>
    <meta charset="UTF-8">                              <!--html注释格式!该句为中文标识-->
        <TITLE>这是一个CGI例子</TITLE>
    </HEAD>
    <BODY>
        <H3>
            搜索框如下: <I>%s</I>
        </H3>
        <FORM ACTION="%s">
            <B>你的搜索内容:</B>
            <INPUT TYPE=hidden NAME=action VALUE=edit>
            <INPUT TYPE=text NAME=person VALUE="%s" SIZE=15>
            <P>
                <B>要展示多少搜索结果:</B>%s
            </P>
            <INPUT TYPE=submit>
        </FORM>
    </BODY>
</HTML>'''

fradio = '<INPUT TYPE=radio NAME=howmany VALUE="%s" %s> %s\n'            #单选按钮

def showForm(who, howmany):                           #生成表单页面用于用户输入
    friends = []
    for i in (0, 10, 25, 50, 100):                    #创建单选按钮文字集
        checked = ''
        if str(i) == howmany:                         #方便用户更新数据,所以这里的howmany依然是用户上次选定的数据,而非默认的0
            checked = 'CHECKED'
        friends.append(fradio % (str(i), checked, str(i)))
    print '%s%s' % (header,formhtml % (who,url,who,''.join(friends)))

reshtml = '''
<HTML>
    <HEAD>
    <meta charset="UTF-8">                            <!--html注释格式!该句为中文标识-->
        <TITLE>这是一个CGI例子</TITLE>
    </HEAD>
    <BODY>
        <H3>
            您搜索的内容如下: <I>%s</I>
        </H3>
        您输入的内容是: <B>%s</B>
        <P>                                           <!--html注释格式!该句为另起一行-->
            您想展示 <B>%s</B> 个结果.
        </P>
        单击<A HREF="%s">这里</A>再次编辑您的数据.
    </BODY>
</HTML>'''

def doResults(who, howmany):
    newurl = url+'?action=reedit&person=%s&howmany=%s' % (quote_plus(who),howmany)       #设置新的url是为了方便用户更新数据  
    print header + reshtml % (who, who, howmany, newurl)

def process():
    error = ''
    form = cgi.FieldStorage()

    if 'person' in form:
        who = form['person'].value.title()
    else:
        who = 'NEW USER'

    if 'howmany' in form:
        howmany = form['howmany'].value
    else:
        if 'action' in form and form['action'].value == 'edit':             #只输入person变量,而不选择howmany,就会连接到错误页面  
            error = '请设置搜索结果的展示数量'
        else:
            howmany = 0

    if not error:
        if 'action' in form and form['action'].value != 'reedit':
            doResults(who, howmany)
        else:
            showForm(who, howmany)
    else:
        showError(error)

if __name__ == '__main__':
    process()

17.3 WSGI-web服务器网关接口

背景:CGI进程针对每个请求进行创建,用完就抛弃。如果请求过多则服务器宕机。
解决办法:一是服务器集成(Apache),二是外部进程(CGI在服务器外部运行)。
WSGI:是定义的一个接口。其目标是在Web服务器和Web框架层之间提供一个通用的API标准,减少之间的互操作性并形成统一的调用方式。
中间件:位于web服务器和web应用之间,在应用执行前或执行后添加一些额外的功能。
WSGI的主旨:是在Web应用和Web服务器之间做了明显的分割。这样有利于分块开发,让团队更方便地划分任务,让Web应用能以一致且灵活的方式在任何兼容WSGI的后端中运行。

猜你喜欢

转载自blog.csdn.net/wutianxu123/article/details/82560873
今日推荐