一、Web应用的本质
- 浏览器发送一个HTTP请求;
- 服务器收到请求,生成一个HTML文档;
- 服务器把HTML文档作为HTTP响应的Body发送给浏览器;
- 浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。
所以,最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。Apache、Nginx、Lighttpd等这些常见的静态服务器就是干这件事情的。
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
正确的做法是底层代码由专门的服务器软件实现,用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
这个接口就是WSGI:Web Server Gateway Interface。
二、wsgI
from wsgiref.simple_server import make_server
def app(env, start_response):
# 核心业务
# 生成响应的对象
start_response('200 OK', [('content-type', 'text/html')]) # 响应头
return ['<h3>Hello, WSGI</h3>'.encode('utf-8')]
httpd = make_server('0.0.0.0', 8000, app)
httpd.serve_foreve(poll_interval=0.5) # 轮询监听的间隔时间
三、Flask
WSGI框架其实一个Web App,就是写一个WSGI的处理函数,针对每个HTTP请求进行响应。
但是如何处理HTTP请求不是问题,问题是如何处理100个不同的URL。
每一个URL可以对应GET和POST请求,当然还有PUT、DELETE等请求,但是我们通常只考虑最常见的GET和POST请求。
一个最简单的想法是从environ
变量里取出HTTP请求的信息,然后逐个判断,
只是这么写下去代码是肯定没法维护了。
代码这么写没法维护的原因是因为WSGI提供的接口虽然比HTTP接口高级了不少,但和Web App的处理逻辑比,还是比较低级,我们需要在WSGI接口之上能进一步抽象,让我们专注于用一个函数处理一个URL,至于URL到函数的映射,就交给Web框架来做。
由于用Python开发一个Web框架十分容易,所以Python有上百个开源的Web框架。这里我们先不讨论各种Web框架的优缺点,直接选择一个比较流行的Web框架——Flask来使用。
from flask import Flask
# 创建Flask对象-Httpd WEB服务对象
app = Flask(__name__) # __name__ 可以是任意的小写字母,表示Flask应用对象名称
# 声明WEB服务的请求资源(指定资源访问的路由)
# RESTful 设计风格中关于资源的动作: 'GET', 'POST', 'PUT', 'DELETE', 'PATCH'
@app.route('/hello', methods=['GET', 'POST'])
def hello():
from flask import request
# request是请求对象(HttpRequest), 它包含请求资源的路径、请求方法、请求头、上传的表单数据、文件等信息。
# 获取请求中查询参数(username, password):
# wsgi-> QUERY_STRING: username=disen&password=123
name = request.args.get('username')
password = request.args.get('password')
# 返回生成的HTML网页内容
return """
<h1>用户登录的信息</h1>
<h3> 用户名: %s </h3>
<h3> 口令: %s </h3>
""" % (name, password)
# 启动flask的WEB服务器
app.run(host="localhost", port=5000)