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 ...
随机推荐
- 焦大:seo思维光年(中)seo体系化
http://www.wocaoseo.com/thread-56-1-1.html 光年的seo培训一直被业界公认为高端的培训,其主导的seo数据化一直对现在很多人的影响至深,比如我自己.但是也有人 ...
- python3+pyqt5+opencv3简单使用
python3+pyqt5+opencv3简单使用(转载) 关于python3下搭建pyqt5(pycharm)参考这条链接. 对于pyqt的使用个人比较建议ui设计与逻辑功能分开开发. 下面介绍下简 ...
- asp .net core 静态文件资源
前言 对静态资源的简单的一个概况,在<重新整理.net core 计1400篇>系列后面会深入. 正文 我们在加入中间件是这样写的: app.UseStaticFiles(); 默认是给w ...
- 微信小程序入门教程
首先请看demo 很简单的静态js就可以实现一款小程序开发. js.json.html.css四个核心文件 序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小 ...
- ABP开发框架的技术点分析(1)
ABP是ASP.NET Boilerplate的简称,ABP是一个开源且文档友好的应用程序框架.ABP不仅仅是一个框架,它还提供了一个最徍实践的基于领域驱动设计(DDD)的体系结构模型.ABP框架可以 ...
- Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能. 下面是一个效果图 ...
- python小白入门基础(四:浮点型和布尔型)
# Number (int float bool complex)# (1) float 浮点型 也就是小数# 表达方式一floatvar = 0.98print(floatvar)print(typ ...
- 简单介绍HTML5 Landmark
最近在进行无障碍相关文档翻译的时候遇到了 landmark 的概念,在网上搜了下发现没有相关的中文资料,因此写一篇博客简单介绍一下. 什么是 Landmark Landmark 是一种用来表示网页组织 ...
- Mysql慢查询(分析工具)
慢查询分析工具[mysqldumpslow] 常用的慢查询日志分析工具 汇总除查询条件外其他完全相同的SQL,并将分析结果按照参数中所指定的顺序输出 语法: mysqldumpslow -s r -t ...
- 外包公司派遣到网易,上班地点网易大厦,转正后工资8k-10k,13薪,包三餐,值得去吗?
作为一个人,我们必须时时刻刻清醒地看待自己,做到不卑不亢才能坚强地活下去. 请肆无忌惮地点赞吧,微信搜索[沉默王二]关注这个在九朝古都洛阳苟且偷生的程序员.本文 GitHub github.com/i ...