基于socke手撸web框架
# 请求首行 b‘GET / HTTP/1.1\r\n #GET /index HTTP/1.1\r\n (index)为浏览器请求地址) # 请求头 Host: 127.0.0.1:8080\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n Upgrade-Insecure-Requests: 1\r\n # User-Agent用来标识是不是浏览器 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36\r\n Sec-Fetch-Mode: navigate\r\n Sec-Fetch-User: ?1\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n Sec-Fetch-Site: none\r\n Accept-Encoding: gzip, deflate, br\r\n Accept-Language: zh-CN,zh;q=0.9\r\n \r\n 请求体
import socket server = socket.socket() server.bind((‘127.0.0.1‘,8080)) server.listen(5) while True: conn, addr = server.accept() data = conn.recv(1024) conn.send(b‘HTTP/1.1 200 OK\r\n\r\n‘) print(data) data = data.decode(‘utf-8‘) current_path = data.split(‘\r\n‘)[0].split(‘ ‘)[1] # print(current_path) if current_path == ‘/index‘: # conn.send(b‘index‘) with open(r‘D:\python脱产10期视频\day51\01 纯手撸html文件.html‘,‘rb‘) as f: conn.send(f.read()) elif current_path == ‘/login‘: conn.send(b‘login‘) else: conn.send(b‘hello world!‘) conn.close()
手撸版web框架
字符山与二进制字符串转换技巧
data = b‘hello world‘ data = str(data,encoding=‘utf-8‘) print(data) data = bytes(data,encoding=‘utf-8‘) print(data)
字符山与二进制字符串转换技巧
基于wsgiref(主要是方便前后端交互的软件)和jinja2(模板渲染)手撸web框架
from wsgiref.simple_server import make_server from 代码.urls import urls from 代码.views import * def run(env,response): """ env是请求相关的数据 response是响应相关的数据 """ # print(env) response(‘200 OK‘,[]) current_path = env.get(‘PATH_INFO‘) # print(current_path) # if current_path == ‘/index‘: # return [b‘index‘] # elif current_path == ‘/login‘: # return [b‘login‘] # 定义一个存储函数名的标志位 func = None for url in urls: # 判断当前url在不在元组内 if url[0] == current_path: # 只要匹配上了 就把url后缀对应的函数名赋值给func func = url[1] # 一旦匹配上 应该立刻退出for循环 节省资源 break # 对变量func做判断 if func: res = func(env) else: res = errors(env) return [res.encode(‘utf-8‘)] if __name__ == ‘__main__‘: server = make_server(‘127.0.0.1‘,8080,run) # 实时监测127.0.0.1:8080地址 一旦有客户端来连接 会自动加括号调用run方法 server.serve_forever() # 启动服务端
代码/url.py
from 代码.views import * urls = [ (‘/index‘,index), (‘/login‘,login), (‘/reg‘,reg), (‘/get_time‘,get_time), (‘/get_user‘,get_user), (‘/get_db‘,get_db), ]
代码/views.py
def index(env): return ‘index‘ def login(env): return ‘login‘ def errors(env): return ‘404 error‘ def reg(env): return ‘reg‘ from datetime import datetime def get_time(env): # 借助于时间模块 现在后端获取到时间数据 current_time = datetime.now().strftime(‘%Y-%m-%d %X‘) with open(r‘templates/02 get_time.html‘,‘r‘,encoding=‘utf-8‘) as f: data = f.read() # data其实就是一串字符串 仅此而已!!! data = data.replace(‘$$time$$‘,current_time) return data from jinja2 import Template def get_user(env): user_dict = {‘username‘:‘jason‘,‘password‘:‘123‘,‘hobby‘:[‘read‘,‘game‘,‘running‘]} with open(r‘templates/03 get_user.html‘,‘r‘,encoding=‘utf-8‘) as f: data = f.read() temp = Template(data) # data为html读出来的所有字符串 res = temp.render(data = user_dict) # 将user_dict传递给前端页面 前端页面通过变量名data(html页面中的{{data}})就能够获取到该字典 return res import pymysql def get_db(env): conn = pymysql.connect( host = ‘127.0.0.1‘, port = 3306, user = ‘root‘, password = ‘123‘, database = ‘day51‘, charset = ‘utf8‘, autocommit = True ) cursor = conn.cursor(pymysql.cursors.DictCursor) sql = "select * from userinfo" affect_rows = cursor.execute(sql) data = cursor.fetchall() # print(data) with open(r‘templates/04 get_db.html‘,‘r‘,encoding=‘utf-8‘) as f: data1 = f.read() temp = Template(data1) res = temp.render(user_list= data) return res
templates
#01 纯手撸html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <h1>要放假了 好嗨皮</h1> </body> </html> #02 get_time.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> $$time$$ </body> </html> # 03 get_user.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <p>{{data}}</p> <p>{{data[‘username‘]}}</p> <p>{{data.password}}</p> <p>{{data.get(‘hobby‘)}}</p> </body> </html> # 04 get_db.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">用户数据展示</h2> <table class="table table-hover table-bordered table-striped"> <thead> <tr> <th>id</th> <th>username</th> <th>password</th> </tr> </thead> <tbody> {%for user_dict in user_list%} <tr> <td>{{user_dict.id}}</td> <td>{{user_dict.name}}</td> <td>{{user_dict.password}}</td> </tr> {%endfor%} </tbody> </table> </div> </div> </div> </body>
html文件
模板渲染
1.模板语法:前端可以使用后端语言的语法,来操作后端传过来的数据
静态网页
数据是写死的,万年不变
动态网页
数据不是写死的 是动态获取到的
比如:
1.后端实时获取当前时间"传递"给前端页面展示
2.后端从数据库获取数据"传递"给前端页面展示
页面渲染:后端把数据传给前端的过程,并把前端改成自己想要的样式。
总结:
.纯手撸web框架 1.手动书写socket代码 2.手动处理http数据 2.基于wsgiref模块帮助我们处理scoket以及http数据 wsgiref模块 1.请求来的时候 解析http数据 帮你打包成一个字典传输给你 便于你操作各项数据 2.响应走的时候 自动帮你把数据再打包成符合http协议格式的样子 再返回给前端 3.封装路由与视图函数对应关系 以及视图函数文件 网站用到的所有的html文件全部放在了templates文件夹下 1.urls.py 路由与视图函数对应关系 2.views.py 视图函数(视图函数不单单指函数 也可以是类) 3.templates 模板文件夹 4.基于jinja2实现模板的渲染 模板的渲染 后端生成好数据 通过某种方式传递给前端页面使用(前端页面可以基于模板语法更加快捷简便使用后端传过来的数据)
原文地址:https://www.cnblogs.com/tfzz/p/11514801.html
时间: 2024-10-24 08:58:49