详解wsgi

详解WSGI

wsgi全称是"Web Server Gateway Interfacfe",web服务器网关接口,wsgi在python2.5中加入,是web服务器和web应用的标准接口,任何实现了该接口的web服务器和web应用都能无缝协作。来看一个形象点的图:

如上图所示,wsgi一端连接web服务器(http服务器),另一端连接应用。目前已经有很多的web框架,如flask、webpy,用户只要简单配置一些路由信息,就能开发出一个web应用。后文中的web框架就等同于应用(application)

一、什么是wsgi

(1)、RESTful只是设计风格而不是标准,而WSGI(Web Server Gateway Interface,Web 服务器网关接口)则是Python语言中所定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。

(2)、WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间进行转化。WSGI将Web组件分成了三类:Web 服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。

   应用:指的是可以被调用的一个对象,一般指的是包含一个__call__方法(实例可以当作函数一般调用)的对象。

   服务器:指的是实现了调用应用的部分。

   中间件:处于服务器和应用两侧,起粘合作用,具体包括:请求处理、environ处理。

(3)、Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。

(4)、Web应用的本质:

       1)、浏览器发送HTTP请求                 

       2)、服务器接收到请求,生成HTML文档

       3)、服务器把HTML文档作为HTTP响应的Body发送给浏览器

       4)、浏览器收到HTTP响应,从HTTP Body取出HTML文档进行显示

接受HTTP请求、解析HTTP请求、发送HTTP响应都是重复的苦力活,如果我们自己来写这些底层代码,还没开始写HTML,先要花半把个月研读HTTP规范。所以底层的代码应该由专门的服务器软件实现,我们用python专注于生成HTML文档。

因为我们不想要接触TCP连接、HTTP原始请求和响应格式。所以需要一个统一的接口,专心用python编写Web业务。

这个接口就是 WSGI:(Web 服务器网关接口)。

https://blog.csdn.net/li_101357/article/details/52748686和https://my.oschina.net/crooner/blog/609030, 这些网页讲wsgi讲的不错。

 比如上面的图中,如果从客户端的浏览器发送一个请求到nginx服务器,如果是静态资源,那么nginx服务器可能就只需直接返回即可,但是如果浏览器发送的是一个需要动态资源的请求,那么就是通过nginx服务器传到wsgi,再通过wsgi讲请求发送到应用程序框架,比如flask,应用程序框架讲数据准备好做成响应的head和body,通过wsgi回传给nginx,最后由服务器进行封装整理发送给客户端浏览器。

了解了HTTP协议和HTML文档,我们其实就明白了一个Web应用的本质就是:

  1. 浏览器发送一个HTTP请求;

  2. 服务器收到请求,生成一个HTML文档;

  3. 服务器把HTML文档作为HTTP响应的Body发送给浏览器;

  4. 浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。

所以,最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。Apache、Nginx、Lighttpd等这些常见的静态服务器就是干这件事情的。

如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。

正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。

1 def application(environ, start_response):
2     start_response('200 OK', [('Content-Type', 'text/html')]) # 这一步就是相当于上图中的第3步,这个start_response由web服务器提供
3     return '<h1>Hello, web!</h1>'  # 这一步就是相当于上图中的第6步

上面代码是一个最简单的应用程序,

上面的application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:

  • environ:一个包含所有HTTP请求信息的dict对象;

  • start_response:一个发送HTTP响应的函数。

application()函数中,调用:

 1 start_response('200 OK', [('Content-Type', 'text/html')]) 

就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个strtuple表示。

通常情况下,都应该把 1 Content-Type 头发送给浏览器。其他很多常用的HTTP Header也应该发送。

然后,函数的返回值

'<h1>Hello, web!</h1>'

将作为HTTP响应的Body发送给浏览器。

整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,我们只负责在更高层次上考虑如何响应请求就可以了。

不过,等等,这个application()函数怎么调用?如果我们自己调用,两个参数environstart_response我们没法提供,返回的str也没法发给浏览器。

所以application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。但是现在,我们只想尽快测试一下我们编写的application()函数真的可以把HTML输出到浏览器,所以,要赶紧找一个最简单的WSGI服务器,把我们的Web应用程序跑起来。

好消息是Python内置了一个WSGI服务器,这个模块叫wsgiref,它是用纯Python编写的WSGI服务器的参考实现。所谓“参考实现”是指该实现完全符合WSGI标准,但是不考虑任何运行效率,仅供开发和测试使用。

 

 通过这个网站https://www.liaoxuefeng.com/wiki/897692888725344/923057057214336可以更好的了解web框架的用处。

原文地址:https://www.cnblogs.com/xiebinbbb/p/13947228.html