Django之WSGI浅谈
一、什么是Web框架
框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统。
浏览器与服务器之间发起HTTP请求:
1.浏览器发送一个HTTP请求;
2.服务器收到请求,生成一个HTML文档;
3.服务器把HTML文档作为HTTP响应的Body发送给浏览器;
4.浏览器收到HTTP响应,从HTTP Body取出HTML文档并显示。
对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
import socket
def handle_request(client):
buf = client.recv()
client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost',))
sock.listen()
while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()
if __name__ == '__main__':
main()
接受HTTP请求、解析HTTP请求、发送HTTP响应都是底层的东西,如果要研究这些底层那得花上一定的时间。因此我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
这个接口就是WSGI:Web Server Gateway Interface。
二、WSGI
Python Web Server Gateway Interface,翻译过来时Python web服务器网关接口,实际上就是一种协议,我们的应用(Django,Flask)实现了WSGI,就可以配合实现了WSGI(uWSGI,gunicorn)的服务器工作了。
以下是结构图:

两级结构
在这种结构里,uWSGI作为服务器,它用到了HTTP协议以及wsgi协议,flask应用作为application,实现了wsgi协议。当有客户端发来请求,uWSGI接受请求,调用flask app得到相应,之后相应给客户端。
这里说一点,通常来说,Flask等web框架会自己附带一个wsgi服务器(这就是flask应用可以直接启动的原因),但是这只是在开发阶段用到的,在生产环境是不够用的,所以用到了uwsgi这个性能高的wsgi服务器。
三级结构
这种结构里,uWSGI作为中间件,它用到了uwsgi协议(与nginx通信),wsgi协议(调用Flask app)。当有客户端发来请求,nginx先做处理(静态资源是nginx的强项),无法处理的请求(uWSGI),最后的相应也是nginx回复给客户端的。
多了一层反向代理有什么好处?
提高web server性能(uWSGI处理静态资源不如nginx;nginx会在收到一个完整的http请求后再转发给wWSGI)
nginx可以做负载均衡(前提是有多个服务器)
保护了实际的web服务器(客户端是和nginx交互而不是uWSGI)
示例1:
from wsgiref.simple_server import make_server def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b'<h1>Hello, web!</h1>'] httpd = make_server('', , application) print('Serving HTTP on port 8080...')
# 开始监听HTTP请求:
httpd.serve_forever()
test1.py
浏览器效果:

注意:
①整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,我们只负责在更高层次上考虑如何响应请求就可以了。
②Python内置了一个WSGI服务器,这个模块叫wsgiref
③application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:
//environ:一个包含所有HTTP请求信息的dict对象;
//start_response:一个发送HTTP响应的函数。
④在application()函数中,调用:
start_response('200 OK', [('Content-Type', 'text/html')])
就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。
start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每个Header用一个包含两个str的tuple表示。
通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。
⑤最后,函数的返回值b'<h1>Hello, web!</h1>'将作为HTTP响应的Body发送给浏览器。
示例2:
调用本身的HTML响应给浏览器
from wsgiref.simple_server import make_server def application(environ, start_response):
# start_response('200 OK', [('Content-Type', 'text/html')]) print(environ['PATH_INFO'])
path = environ['PATH_INFO']
start_response('200 OK', [('Content-Type', 'text/html')])
f1 = open("index1.html", "rb")
data1 = f1.read()
f2 = open("index2.html", "rb")
data2 = f2.read() if path == "/test1":
return [data1]
elif path == "/test2":
return [data2]
else:
return ["<h1>404</h1>".encode('utf8')] return [b'<h1>Hello, web!</h1>'] httpd = make_server('', , application) print('Serving HTTP on port 8080...')
# 开始监听HTTP请求:
httpd.serve_forever()
test2.py
Django之WSGI浅谈的更多相关文章
- 浅谈Django的中间件与Python的装饰器
浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...
- django 浅谈CSRF(Cross-site request forgery)跨站请求伪造
浅谈CSRF(Cross-site request forgery)跨站请求伪造(写的非常好) 本文目录 一 CSRF是什么 二 CSRF攻击原理 三 CSRF攻击防范 回到目录 一 CSRF是什么 ...
- 浅谈flask源码之请求过程
更新时间:2018年07月26日 09:51:36 作者:Dear. 我要评论 这篇文章主要介绍了浅谈flask源码之请求过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考.一起跟随 ...
- 浅谈五大Python Web框架
转载:http://feilong.me/2011/01/talk-about-Python-web-framework 说到Web Framework,Ruby的世界Rails一统江湖,而Pytho ...
- [转]浅谈Python web框架
说到web framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界,各种micro-framework.framework不可胜数,不完全列表见:http://wi ...
- 浅谈测试rhel7新功能时的感受及遇到的问题【转载】
半夜起来看世界杯,没啥激情,但是又怕错误意大利和英格兰的比赛,就看了rhel7 相关新功能的介绍. rhel7的下载地址: https://access.redhat.com/site/downloa ...
- 浅谈ITIL
本节内容 浅谈ITIL CMDB介绍 Django自定义用户认证 Restful 规范 资产管理功能开发 浅谈ITIL TIL即IT基础架构库(Information Technology Infra ...
- 浅谈Python Web的五大框架
说到Web Framework,Ruby的世界Rails一统江湖,而Python则是一个百花齐放的世界.各种micro-framework.framework不可胜数. 尽管还有一大脚本语言PHP也有 ...
- 浅谈 Fragment 生命周期
版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Fragment 文中如有纰漏,欢迎大家留言指出. Fragment 是在 Android 3.0 中 ...
随机推荐
- function参数
expr_without_variable { Z_LVAL($$.u.constant) = ; zend_do_pass_param(&$, ZEND_SEND_VAL, Z_LVAL($ ...
- eclipse中导入SVN项目步骤
1.eclipse中安装SVN插件 在线安装步骤: (1)点击 Help --> Install New Software...(2)在弹出的窗口中点击add按钮,输入Name(任意)和Loca ...
- WebDriverAPI(5)
将当前浏览器截屏 测试网址 http://www.baidu.com Java语言版本实例 @Test public void captureScreenInCurrentWindows() { dr ...
- Java后台 解析JSON的几个方法
1.对象转JSON对象. public static void main(String[] args) { Domain demo = new Domain( "在线JSON校验格式化工具 ...
- Exception message: /bin/bash: line 0: fg: no job control
这个错误是 我本地idea 远程调试hadoop集群出现的 Diagnostics: Exception from container-launch. Container id: container_ ...
- 【转】Spark:一个高效的分布式计算系统
原文地址:http://tech.uc.cn/?p=2116 概述 什么是Spark Spark是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架, ...
- 数据库学习---SQL基础(一)
数据库学习---SQL基础(一) 数据库学习---SQL基础(二) 数据库学习---SQL基础(三) SQL(struct query language)结构化查询语言:一种专门与数据库通信的语言, ...
- Python函数中的可变参数
在Python函数中,还可以定义可变参数. 如:给定一组数字a,b,c……,请计算a2 + b2 + c2 + ……. 要定义出这个函数,我们必须确定输入的参数.由于参数个数不确定,我们首先想到可以把 ...
- 自动换行的两种代码(C#)
最近有个需求,需要将C# winform中的listBox中的内容自动换行, 其实在用listBox前,已经用textBox实现了大部分功能,可惜最后还是有个焦点的问题, 就是textBox中的文字会 ...
- 短视频APP是如何开启你的美好生活的?
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯视频云终端团队发表于云+社区专栏 常青, 2008 年毕业加入腾讯,一直从事客户端研发相关工作,先后参与过 PC QQ.手机QQ. ...