文章目录
- 纯手撸web框架
- 基于wsgiref模块的web服务器的实现
- 动静态网页
- 小结
纯手撸web框架
- socket代码需要我们自己写;
- http格式的数据自己处理(只能拿到用户输入的路由);
import socketserver = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)while True:conn, addr = server.accept()data = conn.recv(1024)data = data.decode("utf-8")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服务器的实现
- 帮助我们封装了socket代码;
- 大字典封装处理了http格式的数据;
web服务网关接口
- 请求来时,帮助我们自动拆分http格式的数据并封装成非常方便处理的数据格式。
- 响应走时,帮我们将数据再打包成符合http格式。
from wsgiref.simple_server import make_server
def index(env):return 'welcome to index page.'def login(env):return 'welcome to login page.'def error(env):return '404 Not Found!'
urls = [('/index',index),('/login',login),
]def run(env,response):''':param env: 请求相关的所有数据:param response: 响应相关的所有数据:return: 返回给浏览器的所有数据'''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])breakif 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: 返回给浏览器的所有数据'''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])breakif 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 = [('/index',views.index),('/login',views.login),
]
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页面中
- 功能需求:
- 后端获取当前时间展示到html页面上;
- 数据字典是从数据库中获取的展示到html页面上;
- views.py
import datetime
from jinja2 import Template
def get_time(env):current_time = datetime.datetime.now()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)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)return res
from app import views
urls = [('/index',views.index),('/login',views.login),('/get_time',views.get_time),('/get_dict',views.get_dict)
]
<!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;
- 请求来时&#xff0c;解析http格式的数据&#xff0c;封装成大字典
env
或request
; - 响应走时&#xff0c;给数据打包成符合http格式&#xff0c;再返回给浏览器