一、什么是wsgi接口
- 先明白什么是cgi,对于动态网站而言,对于客户端的请求服务器需要动态生成网页来响应,当请求被服务器接收后,服务器就把请求中信息,和服务器的信息发送给一个cgi程序,cgi程序接受后处理逻辑,然后输出内容,然后这些内容就送回服务器再传会客户端.cgi程序是基于流方式,所以各种语言都可以写cgi程序.但是每一次请求都会生成一个cgi进程,这种就是所谓的fork-and-exec模式,会导致并发瓶颈的症结(我也不知道会导致什么,反正像你手机开多个软件手机受不了会死机一样...)然后cgi其实一种协议规范,就是写这些cgi程序的规范,你这个cgi程序得这么实现它才能是一个cgi程序.
- wsgi也是一种规范,但是它是python专用的协议.cgi程序可以由不同语言编写,每种语言要有很大的不同,所以对于用python写的网站就用wsgi规范,而不用cgi规范(应该是这样吧..)
二、为什么要使用wsgi规范?
如果要生成动态html,我们既要写返回的网页还要写很多底层代码,比如接受http请求,解析http请求等,这样就很不好,
所以就提出wsgi协议,让写底层的和返回页面分开,让写底层的专注写底层,写返回页面专注写返回页面,互不相干,
但是你写必须按照wsgi这个规范来写,最后才能互相使用.
三、例子
wsgi接口定义非常简单,它只要求Web开发者实现一个函数,就可以响应HTTP请求。我们来看一个最简单的Web版本的“Hello, web!”
def application(environ, start_response):
start_response('200 ok', [('Content-Type', 'text/html')])
return [b'<h1>hello, web!</h1>]
application函数就是符合wsgi标准的一个http处理函数,接收两个参数:
environ:一个包含所有HTTP请求信息的dict对象
start_response:一个发送HTTP响应的函数
application函数中调用了start_response函数,这个函数接受两个参数,一个是http响应码,一个是一组
list表示的http header,每个header用一个包含两个str的tuple表示。
一般至少得发送content-type这个header给浏览器,其他很多常用的http header也应该发送。
然后application函数返回作为http响应body发送给浏览器。
这个函数都没有涉及到解析http等部分,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML,
然后通过start_response()发送Header,最后返回Body。
要调用application函数我们就得传入那两个参数,但是这两个参数我们没法提供,必须由wsgi服务器来调用
wsgi服务器有很多种,python内置了一个wsgi服务器,这个模块叫wsgiref。这个模块应该这是用来开发和测试使用。
四、 运行wsgi服务
先编写实现web应用程序的wsgi处理函数:
def application(environ, start_response):
start_response('200 ok', [('Content-Type', 'text/html')])
return [b'<h1>hello, web!</h1>']
然后,再编写一个server.py,负责启动WSGI服务器,加载application()函数:
#导入wsgiref模块
from wsgiref.simple_server import make_server
#导入我们自己编写的application函数
from wsgi_hello import application
#创建一个服务器,ip地址为空,端口是8000,处理函数是application
httpd = make_server('', 8000, application)
print('Serving HTTP on port 8000...')
#开始监听http请求
httpd.serve_forever()
#确保以上两个文件在同一个目录下
运行服务器
7.png
注意:如果8000端口已被其他程序占用,启动将失败,请修改成其他端口。
启动成功后,打开浏览器,输入http://localhost:8000/,就可以看到结果了:
在命令行可以看到wsgiref打印的log信息:
9.png
我们也可以给url传参数,然后显示出来,需要修改application函数
10.png
小结
反正wsgi一种规范,就定义那些处理函数的规范。HTTP请求的所有输入信息都可以通过environ获得,HTTP响应的输出都可以通start_response()加上函数返回值作为Body。
复杂的Web应用程序,光靠一个WSGI函数来处理还是太底层了,我们需要在WSGI之上再抽象出Web框架,进一步简化Web开发。
最后来一首草东的丧歌,大风吹,跟山海相比我更喜欢这首,还有鬼我也喜欢。晚安。
网友评论