Last updated
Last updated
众所周知,对于所有的 Web 应用(Web 框架),本质上其实就是一个 socket 服务端,用户的浏览器其实就是一个 socket 客户端。
1、自己写 socket,自己处理请求
代表框架是 Tornado(Tornado 有两种模式,可以通过修改配置让它使用自己写的 socket 也可以基于 wsgi)
2、基于 wsgi(Web Server Gateway Interface WEB 服务网关接口),自己处理请求
代表框架是 django
在 Python 中,WSGI(Web Server Gateway Interface)定义了 Web 服务器与 Web 应用(或 Web 框架)之间的标准接口。在 WSGI 的规范下,各种各样的 Web 服务器和 Web 框架都可以很好的交互。
目前咱们的 butterfly 也是基于 WSGI 写的 web 框架
WSGI 接口定义非常简单,它只要求 Web 开发者实现一个函数,就可以响应 HTTP 请求。我们来看一个最简单的 Web 版本的“Hello, web!”:
上面的 application() 函数就是符合 WSGI 标准的一个 HTTP 处理函数,它接收两个参数:
environ:一个包含所有 HTTP 请求信息的 dict 对象;
start_response:一个发送 HTTP 响应的函数。
在 application() 函数中,调用:
就发送了 HTTP 响应的 Header,注意 Header 只能发送一次,也就是只能调用一次 start_response() 函数。start_response() 函数接收两个参数,一个是 HTTP 响应码,一个是一组 list 表示的 HTTP Header,每个 Header 用一个包含两个 str 的 tuple 表示。
通常情况下,都应该把 Content-Type 头发送给浏览器。其他很多常用的 HTTP Header 也应该发送。
然后,函数的返回值 '<h1>Hello, web!</h1>'
将作为 HTTP 响应的 Body 发送给浏览器。
有了 WSGI,我们关心的就是如何从 environ 这个 dict 对象拿到 HTTP 请求信息,然后构造 HTML,通过 start_response() 发送 Header,最后返回 Body。
1 应用程序接收 environ、start_response 这两个参数,返回一个可迭代的对象
environ:一个包含所有 HTTP 请求信息的 dict 对象
start_response:一个发送 HTTP 响应的函数,该函数接收两个参数,一是 HTTP 响应码,二是 HttpHeader 元组列表
2 将应用程序注册到服务器上
3 服务器接收、解析请求,事先准备好 environ 和 start_response,然后调用注册的应用程序。
python 内置了一个 WSGI 服务器,这个模块叫做 wsgiref,不过这个模块没有考虑运行效率,只是为了开发和测试使用。
Model,也就是模型,是对现实的反映和简化。对问题的本质的描述就是 Model。解决问题就是给问题建立 Model。
当我们关注业务问题时,只有描述 “用户所关心的问题” 的代码才是 Model。当你的关注转移到其他问题时,Model 也会相应发生变化。
失去了解决特定问题这一语境,单谈 Model 没有意义。
可以说,View 和 Controller 是 Model 的一部分。
为什么人们要单独把 View 和 Controller 跟 Model 分开呢?
简单来说,Controller 和 View 分别是 Model 的 输入 和 输出。
Model : 也就是模型,是对现实的反映和简化
View : 也就是视图 / 视野,是你真正看到的,而非想象中的 Model
Controller : 也就是控制器,是你用来改变 Model 方式
使用 butterfly 框架时主要是编写 handler
接收 HTTP 请求,解析 HTTP 请求,发送 HTTP 请求等操作就交由 WSGI 服务器去完成,WSGI 接口只负责业务逻辑。
所以主要代码就是完成 WSGI 接口
中内容
即如何处理对应的 environ ,然后返回对应的结果
environ 字典中包含了在 CGI 规范中定义了的 CGI 环境变量,WSGI 变量和一些系统变量
其中 wsgi. 开头的为 WSGI 变量
大写字母的变量为 CGI 环境变量
解析 environ
上述内容是动态开发的根基,只有根据上述内容才可以标准化的动态处理请求。
这些基本上就是 WSGI 协议中定义的主要变量,也基本上涵盖了我们开发时所需要的变量。
environ['QUERY_STRING']
environ['CONTENT_LENGTH']
environ['wsgi.input']
当请求类型是 POST 时,查询字符串不再通过 URL 传递,而是包含在 HTTP 请求体之中来传递。请求体在环境字典中保存为键为“wsgi.input”对应的一个类文件变量。
为了从 wsgi.input 中读出请求体,有必要先知道请求体的长度,即 CONTENT_LENGTH 变量。WSGI 规范中指出,存放有请求体大小的这一 CONTENT_LENGTH 变量是不可靠的,有可能是空值,或者直接缺失,所以获取时应采用 try/except 语法块来进行异常防错。
(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)。
(3)、Web Server 接收 HTTP 请求,封装一系列环境变量,按照 WSGI 接口标准调用注册的 WSGI Application,最后将响应返回给客户端。
让我们一起来构建一个 Web 服务器
View 建议在 实现,即前后端分离
REQUEST_METHOD
POST,GET 等,HTTP 请求的动词标识
SERVER_PROTOCOL
服务器运行的 HTTP 协议。这里当是 HTTP/1.0.
PATH_INFO
附加的路径信息,由浏览器发出.
QUERY_STRING
请求 URL 的“?”后面的部分
CONTENT_TYPE
HTTP 请求中任何 Content-Type 字段的内容
CONTENT_LENGTH
标准输入口的字节数.
HTTP_变量
其他一些变量,例如 HTTP_ACCEPT,HTTP_REFERER 等
wsgi.version
WSGI 版本,要求是元组 (1,0), 标识 WSGI 1.0 协议
wsgi.url_scheme
表示调用应用程序的 URL 的协议,http 或 https
wsgi.input
类文件对象,读取 HTTP 请求体字节的输入流
wsgi.errors
类文件对象,写入错误输出的输出流
wsgi.multithread
如果是多线程,则设置为 True,否则为 False。
wsgi.multiprocess
如果是多进程,则设置为 True,否则为 False。
wsgi.run_once
如果只需要运行一次,设置为 True
wsgi.input
read(size)
wsgi.input
readline()
wsgi.input
readlines(hint)
wsgi.input
iter()
wsgi.errors
flush()
wsgi.errors
write(str)
wsgi.errors
writelines(seq)