热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

纯手撸简易版本的Pythonweb框架

文章目录纯手撸web框架基于wsgiref模块的web服务器的实现动静态网页小结纯手撸web框架socket代码需要我们自己写;http格式的数据自己处理ÿ

文章目录

      • 纯手撸web框架
      • 基于wsgiref模块的web服务器的实现
      • 动静态网页
      • 小结


纯手撸web框架


  1. socket代码需要我们自己写;
  2. http格式的数据自己处理(只能拿到用户输入的路由);

# web框架可以理解成服务器,也就是B/S架构中的服务端
import socketserver = socket.socket()
# 绑定的参数是元组:IP地址、端口号
server.bind(('127.0.0.1',8080))
server.listen(5)while True:conn, addr = server.accept()# 浏览器客户端请求二进制数据,请求数据长度为1024个字节data = conn.recv(1024)# 将获取的二进制数据解码成字符串data = data.decode("utf-8")# print(data,type(data))# 返回请求的状态信息conn.send(b'HTTP/1.1 200 OK\r\n\r\n')# 获取路由根目录进行判断current_path = data.split(' ')[1]if current_path == '/index':conn.send(b'welcome to index Page!')elif current_path == '/login':conn.send(b'welcome to login page!')else:conn.send(b'

Hello World

')conn.close()

在这里插入图片描述

=======================================================================================data的详细数据信息
========================================================================================
GET /login HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
sec-ch-ua: "Google Chrome";v="87", " Not;A Brand";v="99", "Chromium";v="87"
sec-ch-ua-mobile: ?0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.141 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

基于wsgiref模块的web服务器的实现


  1. 帮助我们封装了socket代码;
  2. 大字典封装处理了http格式的数据;

web服务网关接口

  • 请求来时,帮助我们自动拆分http格式的数据并封装成非常方便处理的数据格式。
  • 响应走时,帮我们将数据再打包成符合http格式。

from wsgiref.simple_server import make_server# 业务逻辑的视图函数,封装成views.py
def index(env):return 'welcome to index page.'def login(env):return 'welcome to login page.'def error(env):return '404 Not Found!'# 路由层:urls.py
urls = [('/index',index),('/login',login),
]def run(env,response):''':param env: 请求相关的所有数据:param response: 响应相关的所有数据:return: 返回给浏览器的所有数据'''# 由wxgiref模块帮你处理好http格式的数据,封装成了大字典print(env)response('200 OK',[])# 获取路由根目录current_path = env.get('PATH_INFO')func = Nonefor url in urls:if current_path == url[0]:func = url[1]print(url[0])# 匹配到一个之后,立刻结束for循环break# 判断func是否有值if func:res = func(env)else:res = error(env)# 将字符串转换为二进制数据,返回到路由映射的前端页面return [res.encode('utf-8')]if __name__ == '__main__':"""实时监听127.0.0.1:8080端口地址,如果有客户端发起请求则会交给源函数处理,即触发run函数运行"""server = make_server('127.0.0.1',8080,run)server.serve_forever()

在这里插入图片描述
根据上述的编写逻辑,将代码解耦封装如下:


start_server.py

from wsgiref.simple_server import make_server
from app.urls import urls
from app.views import *def run(env,response):''':param env: 请求相关的所有数据:param response: 响应相关的所有数据:return: 返回给浏览器的所有数据'''# 由wxgiref模块帮你处理好http格式的数据,封装成了大字典print(env)response('200 OK',[])# 获取路由根目录current_path = env.get('PATH_INFO')func = Nonefor url in urls:if current_path == url[0]:func = url[1]print(url[0])# 匹配到一个之后,立刻结束for循环break# 判断func是否有值if func:res = func(env)else:res = error(env)# 将字符串转换为二进制数据return [res.encode('utf-8')]if __name__ == '__main__':"""实时监听127.0.0.1:8080端口地址,如果有客户端发起请求则会交给源函数处理,即触发run函数运行"""server = make_server('127.0.0.1',8080,run)server.serve_forever()

urls.py

from app import views
# 路由层:urls.py
urls = [('/index',views.index),('/login',views.login),
]

views.py

# 业务逻辑的视图函数,封装成views.py
def index(env):return 'welcome to index page.'def login(env):return 'welcome to login page.'def error(env):return '404 Not Found!'

  • urls.py:路由与视图函数的映射关系;
  • views.py:视图函数(后端业务的处理逻辑);
  • templates文件夹:专门用来存储html文件;

按照功能的不同划分之后,后续添加功能只需要在urls.py书写对应关系后,在views.py书写业务逻辑即可。



动静态网页


  • 静态网页:
    • 页面上的数据是写死的
  • 动态网页:
    • 数据是实时获取的,由视图函数将处理的结果反馈到前端的html页面中
    • 功能需求:
      1. 后端获取当前时间展示到html页面上;
      2. 数据字典是从数据库中获取的展示到html页面上;
  • views.py

import datetime
from jinja2 import Template
# 业务逻辑的视图函数,封装成views.pydef get_time(env):current_time = datetime.datetime.now()# 如何将后端获取的数据“传递”给前端的html文件?# 方式一:读写文件with open(r'templates/currentTime.html','r',encoding='utf-8') as f:data = f.read()# 字符串处理函数渲染前端页面current_time = str(current_time)data.replace("current_time",current_time)print(data)# 在后端将html页面处理好之后再返回给前端return datadef get_dict(env):# 定义一个存储用户信息的字典user_dic = {'username':'trainingl','age':21,'hobby':'studying'}user_list = [{'username':'zhangsan','age':21,'hobby':'studying'},{'username':'lisi','age':22,'hobby':'reading'},{'username':'wangwu','age':20,'hobby':'sleeping'},{'username':'zhangliu','age':23,'hobby':'playing'}]with open(r'templates/get_dict.html','r',encoding='utf-8') as f:data = f.read()# 模版语法是在后端起作用的tmp = Template(data)res = tmp.render(user=user_dic,users=user_list)# 给get_dict.html传递了一个值 页面上通过变量名userInfo就能够拿到user_dictreturn res

  • urls.py

from app import views
# 路由层:urls.py
urls = [('/index',views.index),('/login',views.login),('/get_time',views.get_time),('/get_dict',views.get_dict)
]

  • templates/get_dict.html

<!DOCTYPE html>
<html lang&#61;"en">
<head><meta charset&#61;"UTF-8"><title>字典传值</title>
</head>
<body><h2>模版语法之Jinja2模块</h2>{{user}}<br/>取值的三种方式&#xff1a;<br/>{{user.get(&#39;username&#39;)}}<br/>{{user.age}}<br/>{{user[&#39;hobby&#39;]}}<br/><hr/>
<table border&#61;"1px red solid" cellspacing&#61;"0" align&#61;"center"><caption>用户信息表</caption><tr><th>用户名</th><th>年龄</th><th>爱好</th></tr>{% for user_item in users%}<tr><td>{{ user_item.username}}</td><td>{{ user_item.age}}</td><td>{{ user_item.hobby}}</td></tr>{% endfor %}
</table></body>
</html>

在这里插入图片描述

小结

自定义简易版本的web框架请求流程&#xff08;基于wsgiref模块&#xff09;&#xff1a;

  1. 请求来时&#xff0c;解析http格式的数据&#xff0c;封装成大字典envrequest;
  2. 响应走时&#xff0c;给数据打包成符合http格式&#xff0c;再返回给浏览器

推荐阅读
author-avatar
爱做梦的蓝梦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有