本文用一个“网上书店”的web应用示例,简要介绍如何用Python实现基于CGI标准的Web应用,介绍python的cgi模块、cigtb模块对编写CGI脚本提供的支持。
CGI简介
CGI Common Gateway Interface (通用网关接口),是一个Internet标准,允许Web服务器运行一个服务器端程序,称为CGI脚本。一般的,CGI脚本都放在一个名为cgi-bin的特殊文件夹内,这样web服务器就知道到哪里查找cgi脚本。
CGI Architecture Diagram
When a request arrives, HTTP server execute a program, and whatever that program outputs is sent back for your browser to display. This function is called the Common Gateway Interface or CGI, and the programs are called CGI scripts. These CGI programs can be a Python Script, PERL Script, Shell Script, C or C++ program etc.
“网上书店”Web应用目录结构
(操作系统:win7;python版本:3.3)
BookWebApp|
|cgi-bin
------|book_detail_view.py
------|book_list_view.py
------|template
----|yate.py
------|mode
----|Book.by
------|service
----|book_service.py
|resource
------- |books.png
|book.txt
|index.html
|run_server.py
1、Web服务器
所有的Web应用都要在Web服务器上运行,实际上所有的web服务器都支持CGI,无论是Apache、IIS、nginx、Lighttpd还是其他服务器,它们都支持用python编写的cgi脚本。这些web服务器都比较强大,这里我们使用python自带的简单的web服务器,这个web服务器包含在http.server库模块中。
run_server.py:
运行此程序,即启动此web应用。
from http.server import HTTPServer, CGIHTTPRequestHandler
port = 8081
httpd = HTTPServer(('', port), CGIHTTPRequestHandler)
print("Starting simple_httpd on port: " + str(httpd.server_port))
httpd.serve_forever()
2、index.html
首页;URL: “http://localhost:8081/cgi-bin/book_list_view.py” 将调用 cgi-bin文件夹下的book_list_view.py
BookStore
Welcome to My Book Store.
please choose your favorite book, click here.
Enjoy!
3、book_list_view.py
图书清单页面。用户选择要查看的图书,提交表单,然后调动图书详细界面。
#Python标准库中定义的CGI跟踪模块:cgibt
import cgitb
cgitb.enable()
#启用这个模块时,会在web浏览器上显示详细的错误信息。enable()函数打开CGI跟踪
#CGI脚本产生一个异常时,Python会将消息显示在stderr(标准输出)上。CGI机制会忽略这个输出,因为它想要的只是CGI的标准输出(stdout)
import template.yate as yate
import service.book_service as book_service
#CGI标准指出,服务器端程序(CGI脚本)生成的任何输出都将会由Web服务器捕获,并发送到等待的web浏览器。具体来说,会捕获发送到Stdout(标准输出)的所有内容
# 一个CGI脚本由2部分组成, 第一部分输出 Response Headers, 第二部分输出常规的html.
print("Content-type:text/html\n")#Response Headers
#网页内容:有html标签组成的文本
print('')
print('')
print('Book List')
print('')
print('')
print('Book List:')
print(yate.start_form('book_detail_view.py'))
book_dict=book_service.get_book_dict()
for book_name in book_dict:
print(yate.radio_button('bookname',book_dict[book_name].name))
print(yate.end_form('detail'))
print(yate.link("/index.html",'Home'))
print('')
print('')
4、yate.py
自定义的简单模板,用于快捷生成html
def start_form(the_url, form_type="POST"):
return('')
def end_form(submit_msg="Submit"):
return('')
def radio_button(rb_name, rb_value):
return(' ' + rb_value + '')
def u_list(items):
u_string = ''
for item in items:
u_string += '' + item + ''
u_string += ''
return(u_string)
def header(header_text, header_level=2):
return('' + header_text +
'')
def para(para_text):
return('' + para_text + '')
def link(the_link,value):
link_string = '' + value + ''
return(link_string)
5、book_detail_view.py
图书详细页面
import cgitb
cgitb.enable()
import cgi
import template.yate as yate
import service.book_service as book_service
import template.yate as yate
#使用cig.FieldStorage() 访问web请求发送给web服务器的数据,这些数据为一个Python字典
form_data = cgi.FieldStorage()
print("Content-type:text/html\n")
print('')
print('')
print('Book List')
print('')
print('')
print(yate.header('Book Detail:'))
try:
book_name = form_data['bookname' ].value
book_dict=book_service.get_book_dict()
book=book_dict[book_name]
print(book.get_html)
except KeyError as kerr:
print(yate.para('please choose a book...'))
print(yate.link("/index.html",'Home'))
print(yate.link("/cgi-bin/book_list_view.py",'Book List'))
print('')
print('')
6、Book.py
图书类
from template import yate
class Book:
def __init__(self,name,author,price):
self.name=name
self.author=author
self.price=price
@property
def get_html(self):
html_str=''
html_str+=yate.header('BookName:',4)+yate.para(self.name)
html_str+=yate.header('Author:',4)+yate.para(self.author)
html_str+=yate.header('Price:',4)+yate.para(self.price)
return(html_str)
7、book_service.py
图书业务逻辑类
from model.Book import Book
def get_book_dict():
book_dict={}
try:
with open('book.txt','r') as book_file:
for each_line in book_file:
book=parse(each_line)
book_dict[book.name]=book
except IOError as ioerr:
print("IOErr:",ioerr)
return(book_dict)
def parse(book_info):
(name,author,price)=book_info.split(';')
book=Book(name,author,price)
return(book)
8、book.txt
待显示的图书信息(书名;作者;价格)
The Linux Programming Interface: A Linux and UNIX System Prog;Michael Kerrisk;$123.01
HTML5 and CSS3, Illustrated Complete (Illustrated Series);Jonathan Meersman Sasha Vodnik;$32.23
Understanding the Linux Kernel;Daniel P. Bovet Marco Cesati;$45.88
Getting Real;Jason Fried, Heinemeier David Hansson, Matthew Linderman;$87.99
测试结果
运行run_server.py,浏览器访问:http://localhost:8081/
控制台会监控请求的信息:
点击“here”,查看图书清单,即书名列表
选择书名,点击“detail”提交表单,返回该书的详细信息:书名、作者、价格
(转载请注明出处 ^.^)
运维网声明
1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网 享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com