复习 软件开发架构 : c/s b/s
cs client 客户端 -------server 服务端
bs browser 浏览器 -------server 服务端
HTTP协议 : 超文本传输协议 规定了 浏览器 与 服务端之间的数据传输格式
HTTP 四大特性
1 基于 请求响应
2 基于 tcp/ip 协议之上 作用于 应用层
3 无状态 (浏览器 无法保存用户的 状态 后产生了 session 和 cookie)
4 无连接 (请求一次响应一次 之后 立马断开 链接 两者之间没有任何联系)
长连接 websocket
http的请求数据格式: 请求首行(标识HTTP协议版本 和 请求方式) 请求头 (一堆的 k,v 键值对) /r/n (这也是一行 重点) 请求体(携带的是一些敏感的信息如 密码 身份证) http响应数据的格式: 响应首行(标识HTTP协议版本 响应状态码) 响应头(一大堆k,v键值对) /r/n (这也是一行 重点) 响应体(返回给浏览器页面的数据 通常响应体都是html界面)
补充 响应状态码: 用一串简单的数字来表示一些复杂的状态或者提示信息 1XX:服务端已经成功接收了你的数据正在处理 你可以继续提交额外的数据 2XX:服务端成功响应 你想要的数据(请求成功200) 3XX:重定向(当你在访问一个需要登录之后才能访问的页面 你会发现窗口会自动调到登录页面 301 302) 4XX:请求错误(请求资源不存在404,请求不合法不符合内部规定会权限不够403) 5XX:服务器内部错误(500) 补充 请求方式 1.get请求 朝服务端要资源(比如浏览器窗口输入www.baidu.com) 2.post请求 朝服务端提交数据(比如用户登录 提交用户名和密码) URL:统一资源定位符(大白话 就是网址)
‘‘‘ 请求首行 请求方式 http版本信息 b‘GET / HTTP/1.1\r\n 请求体 k v 键值对 Host: 127.0.0.1:9527\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n ....... \r\n‘ 请求体 ....... ‘‘‘ import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind((‘127.0.0.1‘, 8000)) sock.listen() while True: conn, addr = sock.accept() data = conn.recv(8096) # 给回复的消息加上响应状态行 conn.send(b"HTTP/1.1 200 OK\r\n\r\n") conn.send(b"OK") conn.close()
data = b‘hello world‘ data = str(data,encoding=‘utf-8‘) print(data) data = bytes(data,encoding=‘utf-8‘) print(data)
通过 分割 来过去 用户输入的路径 后缀
data = conn.recv(1024) data = str(data,encoding=‘utf-8‘) # 获取get提交数据的后缀 # print(data) current_path = data.split(‘\r\n‘)[0].split(‘ ‘)[1] print(current_path)
# 导入模块 simple 简单的 from wsgiref.simple_server import make_server def run(env , response): # env 信封 是请求相关的 # response 响应 是响应相关的 print(env) # 他是一个大字典 response(‘200 OK‘, []) current_path = env.get(‘PATH_INFO‘) # 获取 后缀 if current_path == ‘login‘: return [b‘login‘] return [b‘he llo baby‘] # 只要有客户端连接 就会触发run方法 if __name__ == ‘__main__‘: server = make_server(‘127.0.0.1‘,8080,run) # 实时监测127.0.0.1 8080地址 一旦有客户端连接 会自动 加括号调用 run方法 # flask伏笔 flask run是一个 类 自动加括号 实例化对象! # host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler
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‘)] 处理之后 每一个函数就不需要编码了
1.urls.py 路由与视图函数的对应关系 >>> urls = [(‘/index‘,index),]
2.views.py 视图函数
动静态网页
静态网页 数据是写死的,万年不变 动态网页 数据不是写死的 是动态获取到的 比如: 1.后端实时获取当前时间"传递"给前端页面展示 2.后端从数据库获取数据"传递"给前端页面展示 传递给前端页面 >>> 页面渲染
推导: 读取文件 然后 使用replace 替换 其中的符号 然后保存 返回客户端
但是 我现在想把一个字典放在 html里面 可以通过 字典取值 我们就需要 jinja2模块
jinja2 pip3 install jinja2 由于flask框架是依赖于jinja2的 所以下载flask框架也会自带jinja2模块 模板的渲染 包含了 模板语法 模板--- html文件 模板语法(贴近python语法) 前端也能够使用后端的一些语法 操作后端传入的数据
{{}} {%%} <p>{{data}}</p> <p>{{data[‘username‘]}}</p> <p>{{data.password}}</p> <p>{{data.get(‘hobby‘)}}</p> {%for user_dict in user_list%} <tr> <td>{{user_dict.id}}</td> <td>{{user_dict.name}}</td> <td>{{user_dict.password}}</td> </tr> {%endfor%}
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) res = temp.render(data = user_dict) # 将user_dict传递给前端页面 前端页面通过变量名data就能够获取到该字典 return res
1.纯手撸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实现模板的渲染
模板的渲染
后端生成好数据 通过某种方式传递给前端页面使用(前端页面可以基于模板语法更加快捷简便使用后端传过来的数据)
☆Django☆---学习Django前的了解 wsgiref jinja2
原文:https://www.cnblogs.com/lddragon/p/11529577.html