路由
路由是 web 框架最核心的功能之一,另外一个是 request->response 处理,路由允许浏览器调用服务端代码中的不同部分。
PATH_INFO
WSGI 服务端把浏览器索要的路径信息记录在了 PATH_INFO 这个变量中并听过 environ 传递给 WSGI 应用端。
下面的伪代码通过无限的 if else 嵌套把所有需要处理的逻辑返回给浏览器。
def giant_wsgi_case_app(environ, start_response):
status = '200 OK' # HTTP Status
# HTTP Headers
headers = [('Content-type', 'text/plain; charset=utf-8')]
start_response(status, headers)
# The returned object is going to be printed
if environ['PATH_INFO'] == '/hello':
return [b"Hello World"]
elif environ['PATH_INFO'] == '/bye':
return [b"Good bye"]
elif ...
...
else:
start_response('404 Not Found', headers)
return [b"Not found"]
这是最原始的路由处理方法,当然几乎没有任何 web 框架会真的这么处理路由。
WSGI 框架路由
我们可以用一个 python 字典去代替繁琐的 if else,许多 wsgi 框架会有一个类似字典的 Mapping 类型。比如 django 可以把路由表放在 urls.py 中,并用正则表达式和可调用的 view 做匹配去响应浏览器的请求。
from django.conf.urls import url
from . import views
app_name = 'polls'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
...
]
另一个 wsgi 框架 pyramid 采用了类似的方法。
with Configurator() as config:
config.add_route('hello', '/hello/{name}')
config.add_view(hello_world, route_name='hello')
app = config.make_wsgi_app()
add_route 把 route_name 和路由的路径模式联系在一起,add_view 把业务处理函数(hello_world)和 route_name 联系在一起。这样当浏览器访问/hello/{name}路径是 hello_world 函数就会被触发。
flask 和 bottle 申明路由的方式相比就不大一样, flask 首先创造了通过装饰器申明路由的方式。下面的代码直接把路由路径“/”和处理函数 hello 联系在了一起,当浏览器访问“/”路径时 hello 函数会被直接调用。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"