起因
最近要写一个工具给商务部门的人使用,而我又不知道用Python写界面,于是想到了使用HTML
页面来做界面的IDEAL,但是我又不想自己的工具以来太多的三方库,那就使用SimpleHTTPServer
吧.
开始使用
SimpleHTTPServer的典型使用方式为:
httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', port), SimpleHTTPServer.SimpleHTTPRequestHandler) sa = httpd.socket.getsockname() httpd.serve_forever()
问题是SimpleHTTPRequestHandler只是用于静态页面,可以看它的源代码中是怎么处理的:
def do_GET(self): """Serve a GET request.""" f = self.send_head() if f: try: self.copyfile(f, self.wfile) finally: f.close()
函数send_head的功能是解析path中的文件名称, 并读取本地对应的文件并返回
函数copyfile的功能就是将文件内容写入到网络通道.
现在我想用SimpleHTTPServer实现生成动态网页的功能,那该怎么办呢?
改造
看了源代码,最简单的解决方式就是继承SimpleHTTPRequestHandler并重写do_GET方法,然后在这里加上自己的处理逻辑
比如我的目标是能够让Web服务器在收到process.html?param=value这个请求时能够根据value
的值进行动态处理,修改后的代码如下
def do_GET(self): if self.path.startswith('/process.html'): try: data = self.process_request() self.gen_file(data) except Exception, e: self.gen_file(e) f = self.send_head_1('result.html') else: f = self.send_head()
process_request():根据请求数据生成动态内容
gen_file():根据动态内容生成本地文件
send_head_1():读取指定的文件并返回
这里比较trick的就是由动态数据生成静态页面的过程:
- 预先准备了一个模板文件, 其中的动态内容用特殊字符串标记
- 生成动态内容后,读取模板文件,将特殊字符串标记替换为动态内容
- 将替换后的内容保存到result.html中,并交由handler去读取内容
- 后续的操作不变
总结
至此,一个简单的Handler就改造完毕, 它可以动态处理指定URI的GET请求, 或者直接读取
本地的文件返回给用户,基本上满足我这个工具的使用场景了.
但是从工程上来讲,这个解决方案是快速却又粗糙的:
- 每次都需要读取模板文件,并没有将它缓存起来
- 动态数据生成后,没必要再创建一个临时的result.html文件,然后去读取,直接将生成的内容
写到管道中就行了. - 路由方案选择的是前缀匹配,而且都是写死的,并不能动态配置