DAY 44 软件开发架构
1.c/s架构
2.b/s架构
# b/s本质也是c/s架构
HTTP协议
"""规定了浏览器与服务端之间数据交互的格式"""
# 1.四大特性
1.基于TCP、IP作用于应用层之上的协议
2.基于请求响应
3.无状态
见你千百遍我都当你如初见
ps:cookie、session、token...
4.无(短)连接
ps:长连接:websocket
# 2.数据格式
请求数据格式
请求首行(请求方法...)
请求头(一大堆K:V键值对)
请求体(并不是所有的请求方法都有 主要用来携带敏感性数据)
响应数据格式
响应首行(响应状态码...)
响应头(一大堆K:V键值对)
响应体(展示给用户的数据)
# 3.响应状态码
用简单的数字来表示一串中文意思
1XX:服务端已经接受到你的数据正在处理,你可以继续提交
2XX:200 OK>>>:请求成功
3XX:重定向(原本想访问A但是内部跳到B)
4XX:403当前请求不符合条件 404请求资源不存在
5XX:服务器内部错误
ps:除了上述统一的响应状态码之外,公司还可以自定义自己的状态码
请求方法
1.get请求
朝别人索要数据
2.post请求
朝别人提交数据
"""
上述两种请求都可以携带额外的参数
get请求
url?username=jason&hobby=mn
post请求
数据是放在请求体里面的
"""
纯手撸web框架
import socket
"""
请求首行
b'GET / HTTP/1.1\r\n
请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"\r\n
sec-ch-ua-mobile: ?0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36\r\n
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\r\n
Sec-Fetch-Site: none\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
请求体
'
"""
server = socket.socket() # 默认就是TCP协议
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
conn, addr = server.accept() # 三次四次挥手
data = conn.recv(1024)
res = data.decode('utf8')
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
# 字符串切割获取地址
path = res.split(' ')[1]
# 判断地址
if path == '/index':
# conn.send(b'index')
with open(r'fh.html','rb') as f:
data = f.read()
conn.send(data)
elif path == '/login':
conn.send(b'login')
conn.close()
问题
-
服务端代码重复
-
手动处理http数据格式过于繁琐
基于wsgiref模块撸
# 解决了上述两个问题
from wsgiref.simple_server import make_server
def run(request,response):
"""
:param request:请求相关的所有数据
:param response:响应相关的所有数据
:return:
"""
response('200 OK',[])
current_path = request.get("PATH_INFO")
if current_path == '/index':
return [b'index']
elif current_path == '/login':
return [b'login']
return [b'404 error']
if __name__ == '__main__':
server = make_server('127.0.0.1',8080,run) # 一旦被访问会全部交给run函数处理
server.serve_forever()
问题
-
网址很多的情况下如何匹配
-
网址多匹配如何解决
-
功能复杂代码块如何解决
封装处理
1.定义一个网址与功能函数的对应关系
# 地址与功能的对应关系
urls = [
('/index',index_func),
('/login',login_func),
('/reg',reg_func),
]
2.按照功能的不同划分成不同的py文件
urls.py views.py 服务端.py
3.书写服务端代码
func = None
# for循环判断
for url_tuple in urls: # (),()
if current_path == url_tuple[0]:
# 将匹配到的函数名赋值给func变量
func = url_tuple[1]
break
# 判断func是否有值
if func:
# 执行对应的函数
res = func(request)
else:
res = errors(request)
return [bytes(res,encoding='utf8')]
动静态网页
静态网页
数据全部都是写死的
动态网页
数据来源于后端(代码、数据库)
1.访问网址展示当前时间(由后端模块生成并展示到html页面)
def get_time_func(request):
from datetime import datetime
current_time = datetime.now().strftime('%Y-%m-%d %X')
with open(r'get_time.html','r',encoding='utf8') as f:
data = f.read() # 字符串
data = data.replace('sadadadad',current_time)
return data
2.后端有一个字典,将该字段传递给html页面,并且在该页面上还可以使用字典取值的各种操作
jinja2模块
pip3 install jinja2
ps:该模块是flask框架必备的模块 所以下载flask也会自动下载该模块
def get_dict_func(request):
user_dict = {"username":'jason','password':123,'hobby':'study'}
from jinja2 import Template
with open(r'templates/get_dict.html','r',encoding='utf8') as f:
data = f.read() # 字符串
temp = Template(data)
# 将user_dict传递给get_dict.html页面 在该页面上使用变量名user_data调用
res = temp.render(user_data=user_dict)
return res
模板语法(用近似于python的语法在html文件上操作数据)
{{user_data}}
{{user_data['username']}}
{{user_data.get('password')}}
{{user_data.hobby}}
{%for user_dict in data_list%}
<tr>
<td>{{user_dict.id}}</td>
<td>{{user_dict.name}}</td>
<td>{{user_dict.age}}</td>
</tr>
{%endfor%}
3.获取MySQL数据库数据展示到页面上
def get_db_func(request):
import pymysql
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123',
db='db666',
charset='utf8',
autocommit=True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = 'select * from userinfo'
affect_rows = cursor.execute(sql)
res1 = cursor.fetchall() # [{},{},{}]
with open(r'templates/get_db.html','r',encoding='utf8')