web框架推导
django
引言
所有的web应用本质上就是一个socket服务端,而用户的浏览器。
软件开发架构
cs架构
bs架构
本质上,bs架构也是cs架构
- http协议
网络协议
http协议 数据传输是明文的
https协议 数据传输是密文的
websocket协议 数据传输是密文的
四大特性:
1.基于请求响应
2.基于TCP,IP作用于应用层之上的协议
3.无状态
4.短/无链接
数据格式(请求格式)
请求首行
请求头
请求体
响应状态码
1xx
2xx 200
3xx 301 302
4xx 403 404
5xx 500
原始自定义web框架
# 你可以将web框架理解成服务端
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)
print(data)
data = data.decode("utf-8")
conn.send(b"hello web")
conn.close()
web服务的本质就是在上述代码的基础上扩展出来的
在网页上直接输入ip+port(127.0.0.1:8080)得到的结果是127.0.0.1 发送的响应无效。原因是写的服务端向客户端发送的数据格式不符合HTTP协议。
但是在服务器上可以收到网页的请求如下:
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: cross-site\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
- 想让客户端(浏览器)收到服务端发送的数据,需要遵循HTTP协议,因此在给客户端回复消息的时候必须按照HTTP协议规则加上响应状态行
低配版自定义web框架--遵循HTTP协议
# 你可以将web框架理解成服务端
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)
print(data)
data = data.decode("utf-8")
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
conn.send(b"hello web")
conn.close()
中配版自定义web框架---根据不同的url返回不同的内容
- 低配版 ----if判断
原理:将浏览器发送到服务端的数据进行处理,然后做一个判断即可
b'GET /index HTTP/1.1\r\n
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: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36\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;q=0.9\r\n
Sec-Fetch-Site: cross-site\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Sec-Fetch-Dest: document\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n\r\n'
# 你可以将web框架理解成服务端
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)
current_path = data.decode("utf-8").split(" ")[1]
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
if current_path =="/index":
conn.send(b"hello index")
elif current_path =="/login":
conn.send(b"hello login")
else:
conn.send(b"404 error")
conn.close()
中配版---使用函数与列表结合
低配版的问题:虽然解决了不同url路径返回不同内容的需求,但是如果有很多路径要判断怎么办?难道挨个写if判断?
# 你可以将web框架理解成服务端
def index():
return "hello index"
def login():
return "hello login"
def error():
return "404 error"
urls = [
("/login",login),
("/index",index),
]
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)
current_path = data.decode("utf-8").split(" ")[1]
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
func = None
for url in urls:
if current_path ==url[0]:
func = url[1]
break
if func:
ret = func()
else:
ret = error()
conn.send(ret.encode("utf-8"))
conn.close()
上面的代码的不足之处
1.代码重复(服务端代码所有人都要重复写)
2.手动处理http格式的数据 并且只能拿到url后缀 其他数据获取繁琐(数据格式一样处理的代码其实也大致一样 重复写)
3.并发的问题
基于wsgiref模块
from wsgiref.simple_server import make_server
def index(env):
return 'index'
def login(env):
return "login"
def error(env):
return '404 error'
# url与函数的对应关系
urls = [
('/index',index),
('/login',login),
]
def run(env,response):
'''
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return: 返回浏览器的数据
'''
# print(env) #大字典 wsgiref模块帮你处理好http格式的数据 封装成了字典让你更加方便的操作
# 从env中取
response("200 OK",[]) # 响应首行 响应头
current_path = env.get("PATH_INFO")
# 定义一个变量 存储匹配到的函数名
func = None
for url in urls:
if current_path == url[0]:
# 将url对应得函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束for循环
# 判断func是否有值
if func:
res = func(env)
else:
res = error(env)
return [res.encode("utf-8")]
if __name__ =="__main__":
server = make_server("127.0.0.1",8080,run)
"""
会实时监听127.0.0.1:8080地址 只要有客户端来了
都会交给run函数处理(加括号触发run函数的运行)
fladk启动源码
make_server("127.0.0.1",8080,obj)
__call__
"""
server.serve_forever() # 启动服务端
代码拆分及主要文件说明
urls.py文件
from views import *
# url与函数的对应关系
urls = [
('/index',index),
('/login',login),
]
views.py文件
def index(env):
return 'index'
def login(env):
return "login"
def error(env):
return '404 error'
基于wsgiref模块
from wsgiref.simple_server import make_server
from urls import urls
from views import *
def run(env, response):
response('200 OK', []) # 响应首行 响应头
current_path = env.get('PATH_INFO')
func = None
for url in urls: # url (),()
if current_path == url[0]:
# 将url对应的函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束for循环
# 判断func是否有值
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')]
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever() # 启动服务端
文件说明:
urls.py 路由与视图函数对应关系
view.py 视图函数(后端业务逻辑)
templates文件夹 专门用于存储html文件
按照功能的不同拆分之后 后续添加功能只需要在urls.py书写对应关系 然后去views.py书写业务逻辑即可
返回html文件
urls.py文件
from views import *
# url与函数的对应关系
urls = [
('/index',index),
('/login',login),
("/html",html)
]
views.py文件
def index(env):
return 'index'
def login(env):
return "login"
def html(env):
with open("html.html","r",encoding = "utf-8") as f:
data = f.read()
return data
def error(env):
return '404 error'
基于wsgiref模块
from wsgiref.simple_server import make_server
from urls import urls
from views import *
def run(env, response):
response('200 OK', []) # 响应首行 响应头
current_path = env.get('PATH_INFO')
func = None
for url in urls: # url (),()
if current_path == url[0]:
# 将url对应的函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束for循环
# 判断func是否有值
if func:
res = func(env)
else:
res = error(env)
return [res.encode('utf-8')]
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run)
server.serve_forever() # 启动服务端
- 动静态网页
静态网页
页面上的数据是直接写死的 万年不变
动态网页
数据是实时获取的
eg:
1.后端获取当前时间展示到html页面上
2.数据是从数据库中获取的展示到html页面上
动态网页制作:后端获取当前时间展示到html页面上
import datetime
def get_time(env):
current_time = datetime.datetime.now().strftime("%Y-%m-%d %X")
#如何将后端获取的数据传递给前端html文件
with open("mytime.html","r",encoding="utf-8") as f:
data = f.read()
# data 就是一堆字符串
data = data.replace("wdefewfew",current_time) # 在后端将html页面处理好之后再返回给前端
return data
模版语法
原理:
- 模版的原理就是字符串替换,只要在HTML页面中遵循jinja2的语法规则书写,内部就会按照指定的语法进行替换
模版语法案例一
#注意要将该函数与路由对应关系加入到urls.py
from jinja2 import Template
def get_dict(env):
user_dict ={"username":"jason","age":18,"hobby":"read"}
with open(r"templates/04 get_dict.html","r",encoding=
"utf-8") as f:
data = f.read()
tmp = Template(data)
res = tmp.render(user_dic)
#给get_dict.html传递一个值 页面上通过变量名user就能够拿到user_dict,变量名是随意的,不过要见名知意
return res
#get_dict
<body>
{{xx}} //获取字典
//获取字典中的值的三种方式
{{xxx.get("username")}}
{{xxx["password"]}}
{{xxx.hobbies}}
</body>
- 模版语法案例二----后端数据库中数据展示到前端页面
def get_mysql(env):
conn = pymysql.connect(
host = "127.0.0.1",
port = 3306,
user = "root",
password = "123",
database = "user",
charset = "utf8"
autocommit = True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from info;"
rows = cursor.execute(sql)
data_list = cursor.fetchall()
with open(r"template/get_mysql.html","r",encoding="urf-8") as f:
data = f.read()
temp = Template(data)
res = temp.render(data_list=data_list)
return res
自定义简易版本web框架流程图
wsgiref
1.请求来的时候解析http格式的数据 封装成大字典
2.响应走的时候给数据打包成符合http格式 再返回给浏览器
web框架推导的更多相关文章
- 自定义web框架(django)
Django基础了解知识 HTTP协议(超文本传输协议) HTTP协议 四大特性: 基于TCP/IP之上作用于应用层 基于请求响应 无状态 引申出cookie session token-- 无连接 ...
- Web开发框架推导
本文欲回答这样一个问题:在 「特定环境 」下,如何规划Web开发框架,使其能满足 「期望 」? 假设我们的「特定环境 」如下: 技术层面 使用Java语言进行开发 通过Maven构建 基于Spring ...
- Django-手撸简易web框架-实现动态网页-wsgiref初识-jinja2初识-python主流web框架对比-00
目录 自己动手实现一个简易版本的web框架 手撸一个web服务端 根据请求 url 做不同的响应处理 基于wsgiref模块实现服务端 用wsgiref 模块的做的两件事 拆分服务端代码 支持新的请求 ...
- 自创Web框架之过度Django框架
目录 自创Web框架之过度Django框架 软件开发架构 HTTP协议 Web框架之"撸起袖子加油干" Web框架之通过wsgiref加油干 封装优化处理 动静网页 jinjia2 ...
- Python(九)Tornado web 框架
一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过 ...
- 转-基于NodeJS的14款Web框架
基于NodeJS的14款Web框架 2014-10-16 23:28 作者: NodeJSNet 来源: 本站 浏览: 1,399 次阅读 我要评论暂无评论 字号: 大 中 小 摘要: 在几年的时间里 ...
- 初步认识Node 之Web框架
上一篇我们认识了Node是什么之后,这一篇我们主要了解的就是它的框架了.而它的框架又分为两大类,Web框架和全栈框架,接下来我们一个一个的来了解. Web框架 Web框架可以细分为Web应用程序 ...
- 【原】Go语言及Web框架Beego环境无脑搭建
本文涉及软件均以截至到2013年10月12日的最新版本为准 1. 相关软件准备: 1) go1.2rc1.windows-386.msi,对应32位windows系统安装使用 下载地址: https: ...
- 【译】什么是 web 框架?
Web 应用框架,或者简单的说是“Web 框架”,其实是建立 web 应用的一种方式.从简单的博客系统到复杂的富 AJAX 应用,web 上每个页面都是通过写代码来生成的.我发现很多人都热衷于学习 w ...
随机推荐
- 使用BeetleX在Linux下部署.NET多站点服务
在windows下常用IIS来部署.NET的多站点服务,但在Linux下就没这么方便了:虽然可以使用一些代理服务器如nginx,jexus等来反代或部署应用,但nginx对.NET应用的 ...
- vmware虚拟机Bridged(桥接模式)、NAT(网络地址转换模式)、Host-Only(仅主机模式)详解
原文来自http://note.youdao.com/share/web/file.html?id=236896997b6ffbaa8e0d92eacd13abbf&type=note 我怕链 ...
- python给excel文件加密码,并重新生成文件
需安装pywin32 pip install pywin32 直接上源码.简单几行就搞定 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. ...
- vue项目打包上线发现 360 浏览器不兼容?
分享链接: 文档:解决vue 和 360 浏览器兼容问题.note链接:http://note.youdao.com/noteshare?id=41914c6dbb4238d765b26d59aa05 ...
- 为什么一个还没毕业的大学生能够把 IO 讲的这么好?
Java IO 是一个庞大的知识体系,很多人学着学着就会学懵了,包括我在内也是如此,所以本文将会从 Java 的 BIO 开始,一步一步深入学习,引出 JDK1.4 之后出现的 NIO 技术,对比 N ...
- RGB打水印在YUV图片上
一. 概述 将RGB图片打在YUV上需要注意的是, 字体之外应该透明, 否则背景也会被覆盖不好看, 所以RGB必须有透明度, 本测试格式为BMP ARGB8888(也即B是最低字节, A是最高字节 ...
- MySQL查询point类型类型的坐标,返回经度纬度
location字段为point类型的空间坐标 SELECT id, name, address, x(location) as 经度, Y(location) as 纬度, ROUND( 6378. ...
- JDK8(jdk-8u212-windows-x64) 下载 安装 及设置
JDK8 下载页面 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 19.8.2 ...
- sqlserver语句的执行顺序
执行顺序: 1.from 2.where 3.group by 4.having 5.根据select 关键之后的要显示的字段,进行结果集显示 6.order by 对最终结果集进行排序 7.top/ ...
- docker下部署jira破解版
1. 制作Docker破解容器 在/opt/jira下新建一个Dockerfile文件 touch Dockerfile 编辑Dockerfile文件 vim Dockerfile FROM cpta ...