Web框架原理

前提

一个web框架需要包含的组件或者功能有:

  1. request and response
  2. cookies and session
  3. template engine
  4. wsgi app and wsgi server

对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

wsgi

首先要了解WSGI的相关知识,如下:

  • web server:指的是软件程序,它从客户端接受请求,然后返回一个Response,需要注意的是它不创建Response,web app才是创建Response的主体。
  • web app:根据url来创建响应并将响应传回给web server。
  • WSGI:是一个规范,描述了web server如何与web app交互、web app如何处理请求,它规定每个app必须是一个可调用的对象(方法或者类),接受两个参数environ和start_response。

实现

web server

environ和start_response都是服务器提供的,所以服务端这边需要提供如下:

  1. 准备environ参数;
  2. 定义start_response函数;
  3. 调用程序端的可调用对象;

代码具体如下(取自PEP 333):

import os, sys
enc, esc = sys.getfilesystemencoding(), ‘surrogateescape‘def unicode_to_wsgi(u):
    # Convert an environment variable to a WSGI "bytes-as-unicode" string
    return u.encode(enc, esc).decode(‘iso-8859-1‘)def wsgi_to_bytes(s):
    return s.encode(‘iso-8859-1‘)def run_with_cgi(application):
    # environ参数,里面是HTTP请求的环境变量
    environ = {k: unicode_to_wsgi(v) for k,v in os.environ.items()}
    environ[‘wsgi.input‘]        = sys.stdin.buffer
    environ[‘wsgi.errors‘]       = sys.stderr
    environ[‘wsgi.version‘]      = (1, 0)
    environ[‘wsgi.multithread‘]  = False
    environ[‘wsgi.multiprocess‘] = True
    environ[‘wsgi.run_once‘]     = True
    if environ.get(‘HTTPS‘, ‘off‘) in (‘on‘, ‘1‘):
        environ[‘wsgi.url_scheme‘] = ‘https‘
    else:
        environ[‘wsgi.url_scheme‘] = ‘http‘
    headers_set = []
    headers_sent = []    # 将应答的数据输出到终端
    def write(data):
        out = sys.stdout.buffer        if not headers_set:             raise AssertionError("write() before start_response()")        elif not headers_sent:             # Before the first output, send the stored headers
             status, response_headers = headers_sent[:] = headers_set
             out.write(wsgi_to_bytes(‘Status: %s\r\n‘ % status))             for header in response_headers:
                 out.write(wsgi_to_bytes(‘%s: %s\r\n‘ % header))
             out.write(wsgi_to_bytes(‘\r\n‘))
        out.write(data)
        out.flush()    # 根据程序传过来的状态和头部参数设置响应的状态和头部
    def start_response(status, response_headers, exc_info=None):
        if exc_info:            try:                if headers_sent:                    # Re-raise original exception if headers sent
                    raise exc_info[1].with_traceback(exc_info[2])            finally:
                exc_info = None     # avoid dangling circular ref
        elif headers_set:            raise AssertionError("Headers already set!")
        headers_set[:] = [status, response_headers]        return write    # 调用客户端的对象,并且输出返回的结果
    result = application(environ, start_response)    try:        for data in result:            if data:    # don‘t send headers until body appears
                write(data)        if not headers_sent:
            write(‘‘)   # send headers now if body was empty
    finally:        if hasattr(result, ‘close‘):
            result.close()

web app

因为服务端和客户端需要共同遵守WSGI协议内容,所以客户端这边需要使用到服务端提供的environ和start_response,web app需要返回的类型需要是可迭代的。这里分为三种类型的实现,分别是函数,类,实例;

函数

HELLO_WORLD = b"Hello world!\n"# 1. 可调用对象是一个函数def application(environ, start_response):
    # HTTP response code and message
    status = ‘200 OK‘
    # 应答的头部是一个列表,每对键值都必须是一个 tuple。
    response_headers = [(‘Content-Type‘, ‘text/plain‘),
                        (‘Content-Length‘, str(len(HELLO_WORLD)))]    # 调用服务器程序提供的 start_response,填入两个参数
    start_response(status, response_headers)    # 返回必须是 iterable
    return [HELLO_WORLD]

# 2. 可调用对象是一个类class AppClass:
    """这里的可调用对象就是 AppClass 这个类,调用它就能生成可以迭代的结果。          使用方法类似于:
        for result in AppClass(env, start_response):
             do_somthing(result)
    """
    def __init__(self, environ, start_response):
        self.environ = environ
        self.start = start_response    def __iter__(self):
        status = ‘200 OK‘
        response_headers = [(‘Content-type‘, ‘text/plain‘)]
        self.start(status, response_headers)        yield HELLO_WORLD

实例

# 3. 可调用对象是一个实例class AppClass:
    """这里的可调用对象就是 AppClass 的实例,使用方法类似于:
        app = AppClass()
        for result in app(environ, start_response):
             do_somthing(result)
    """
    def __init__(self):
        pass
    def __call__(self, environ, start_response):
        status = ‘200 OK‘
        response_headers = [(‘Content-type‘, ‘text/plain‘)]
        self.start(status, response_headers)        yield HELLO_WORLD
时间: 2024-10-09 21:39:40

Web框架原理的相关文章

第52篇 WEB框架原理 Django安装与项目的创建

1. Web框架的原理 1. 浏览器(socket客户端) 网站的服务器(socket服务端) 2. HTTP协议 1. 目前用的版本:HTTP/1.1,最新的版本是HTTP/2 2. http默认端口80,https默认端口是443 3. 请求(request)的消息格式 1. 请求行 2. 请求头 3. 空行 4. 请求数据 4. 响应(response)的消息格式 1. 响应行 2. 响应头 3. 空行 4. 响应数据 3. Web框架原理总结 1. 收发socket消息(Web服务器程序

Django之Web框架原理

Django之Web框架原理 为什么要学习所谓的Web框架原理 因为不管是django也好 市场上最火的什么MVC框架也好他就是基于这一套东西,来给你进行一些功能的封装让你用着特别方便,我们要做的不止是学会这些框架学框架的时候要有自己的想法,要知道这个框架的这个地方自己好像试着做也能做出来废话不多说 铁子 奥力给!! Web框架是什么 Web 应用框架,或者简单的说是“Web 框架”,其实是建立 web 应用的一种方式.从简单的博客系统到复杂的富 AJAX 应用,web 上每个页面都是通过写代码

python django框架(一)

s4day63内容回顾: 1. 安装 2. 创建用户 + 授权 3. 连接 - 数据库 终端创建数据库(字符编码) - 数据表 终端 ORM pymysql create ...)engine=innodb - 数据行 增 删 改 查 - limit - group by .... 关闭 问题:简述ORM原理? day64内容 1. 自己开发Web框架 - socket - http协议 - HTML知识 - 数据库(pymysql,SQLAlchemy) HTTP特点: 无状态.短连接 TCP

DjangoContenttype

---恢复内容开始--- 一切优化,最终都是关于需求的优化,本文介绍需求确定之后的数据库表结构设计优化. 引入 我们一直情调的一句话是,编程是数据结构和算法的结合,所谓数据就是用户需要访问和操作的资源,比如购物类App里面的商品,图书,衣服,鞋帽等等,算法就是我们通过一系列的获取数据,过滤数据,汇总并编排数据并最终展示给用户的一个过程. 算法的实现复杂度非常重要,因为它直接关乎到用户体验,用户体验的重要性,我们不需要再次强调了,算法实现简单则用户体验好,反则用户体验差,而算法的实现复杂度直接与数

python 开发必备知识

Python基础语法入门(2天): 1.Python语言介绍.发展史.与其它语言的对比 2.编程语言分类.解释型vs编译型优缺点 3.Python环境安装.Pycharm IDE使用 4.基本语法:变量.常量命名规范.程序执行.编码区别 5.二进制的演化与运算 6..pyc是什么鬼? 7.实战案例:用户交互小程序 8.基本数据类型:int.str.bool.list.dict.set 9.流程控制:if.elif.else.for.while语句 10.break vs continue的作用

博客园目录导航 持续更新中~~

目录 博客园目录导航 python语言学习 python基础入门 python函数 python模块 python面向对象 网络编程 并发编程 Mysql数据库 初识数据库 mysql数据库安装 mysql支持数据类型 SQL语句 mysql约束 单表多表查 SQL注入风险 web前端 HTML CSS JavaScript Vue jQuery Bootstrap Django框架 Flask框架 算法 爬虫 人工智能 博客园装饰 博客园目录导航 python语言学习 python基础入门 计

Spring 框架原理

[spring框架原理] Spring框架原理 [博主]高瑞林 [博客地址]http://www.cnblogs.com/grl214 写给读者的话 ------亲爱的读者感谢您对小编的支持,当我正值青春的年纪里,很高兴能结识了一群花样年华的你们.当幸福像花儿一样盛开,请允许我记住在花季里始终如一关注我的你  谢谢您一直在路上!让我们一起带着欢乐走进Java的世界! 目录 Spring框架的概念 Spring中IOC Spring框架原理 beanFactory和AppilcationConte

Authentication in .NET Web Api

在介绍WebApi这个小demo前,先来简单说一下OAuth这个东西. OAuth开放授权,用户可以对自己的资源进行第三方授权,那么第三方就可以不用你的账号密码就可以访问你授权的资源了.比如一些论坛直接用qq账号登陆.微信公众号等,都是OAuth的应用体现. 这里的WebApi的demo也是一样,用户只有获得授权token才能访问api,有人对这个token比较好奇,然而OAuth2.0并没有介绍token的算法,只是介绍了如何使用,Google.Twitter倒是明确说明使用了这种Bearer

框架 day68 SpringMVC入门(框架原理,springmvc和mybatis整合)

第一天:注解开发基础(springmvc入门) springmvc框架原理(掌握) DispatcherServlet前端控制器.HandlerMapping处理器映射器.HandlerAdapter处理器适配器.ViewResolver视图解析器 springmvc入门程序 目标:加深对springmvc三大组件的认识 查询商品信息 重点掌握注解的HandlerMapping处理器映射器.HandlerAdapter处理器适配器(掌握) springmvc和mybatis整合(掌握) 通过一个