概述
什么是框架?
在生活中就像我们想到的一样,框架指的我们在做一件事情的时候搭的骨架来完成基础的功能。
例如盖楼,开发商建的毛坯房就是楼的骨架,毛坯房的基础功能就是能住。如果想住的舒服
用户根据自己的需求来摆放物品。例如客厅放沙发,电视。主卧放床和衣柜等等。
例如明星开演唱会,舞台的搭建就是一个骨架,舞台基础的功能就是明星能有地方唱歌跳舞,如果想要气氛,可以在舞台上摆放不同的物品。
程序中的框架和生活中搭建的框架的功能是相同的,框架来完成一些基础的工作,
程序员在此基础上开发实现自己业务功能的代码;
把程序员从繁琐的重复性的代码中解脱出来,提交开发效率;
WEB框架的本质
我们可以这样理解:所有的Web应用框架本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 一些常用框架(Django、Tornado、Flash)是对socket服务端进行的封装,使得基础功能更加完善。
自定义初始web框架
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(128) while True: print('等待客户连接') client_sk,addr=server_sk.accept() content=client_sk.recv(1024) #默认是二进制内容 print(content) #接收到是内容是请求报文 content=content.decode('utf-8') print(content) #给浏览器发送内容 client_sk.send('HTTP/1.1 200 OKrn'.encode('utf-8')) #设置响应首行 # client_sk.send('Content-Type: text/html;charset=gbk') client_sk.send('rn'.encode('utf-8')) #设置响应空格 client_sk.send('很好'.encode('utf-8')) #设置响应体内容,可以发送英文,但是发送中文会变化乱码 client_sk.close()
我们通过十几行代码简单地演示了web 框架的本质。
接下来就让我们继续完善我们的自定义web框架吧!
扩展:
解决返回给浏览器中文乱码问题:
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(23) #可以连接客户端的个数 while True: client_sk,addr=server_sk.accept() content=client_sk.recv(1024).decode('utf-8') print(content) #向浏览器发送内容 msg1='HTTP/1.1 200 OKrn'.encode('utf-8') #设置响应首行 # 设置响应头,告诉浏览器返回的是文本类型的html,并且以utf-8格式解码 msg2='Content-Type:text/html;charset=utf-8rn'.encode('utf-8') #通过设置响应头来告诉浏览器以什么方式解码来避免中文出现乱码 msg3='rn'.encode('utf-8') msg4='你好浏览器'.encode('utf-8') client_sk.send(msg1) client_sk.send(msg2) client_sk.send(msg3) client_sk.send(msg4) client_sk.close()
(2).根据不同的路径返回不同的内容
如何让我们的Web服务根据用户请求的URL不同而返回不同的内容呢?
我们可以从请求相关数据里面拿到请求URL的路径,然后拿路径做一个判断...
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(34) while True: client_sk,addrs=server_sk.accept() content=client_sk.recv(1024).decode('utf-8') print("客户端发来贺电:") print(content) #切出index con=content.split(' ') print(con) con1=con[1].split('/') path=con1[1] #根据url中的内容返回不同页面 if path=='index': msg='这是{}页面'.format(path).encode('utf-8') elif path=='home': msg='这是{}页面'.format(path).encode('utf-8') else: msg='sorry {} not find'.format(path).encode('utf-8') #向页面返回内容 msg1='HTTP/1.1 200 okrn'.encode('utf-8') msg2='Content-Type:text/html;charset=utf-8rn'.encode('utf-8') msg3='rn'.encode('utf-8') client_sk.send(msg1) client_sk.send(msg2) client_sk.send(msg3) client_sk.send(msg) #关闭客户端 client_sk.close()
(3).根据不同的路径返回不同的内容--函数版
上面的代码解决了不同URL路径返回不同内容的需求。
但是问题又来了,如果有很多很多路径要判断怎么办?难道要挨个写if判断? 当然不用,我们有更聪明的办法。
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(34) while True: client_sk,addrs=server_sk.accept() content=client_sk.recv(1024).decode('utf-8') print("客户端发来贺电:") print(content) #切出index con=content.split(' ') print(con) con1=con[1].split('/') path=con1[1] # 向页面返回内容 msg1 = 'HTTP/1.1 200 okrn'.encode('utf-8') msg2 = 'Content-Type:text/html;charset=utf-8rn'.encode('utf-8') msg3 = 'rn'.encode('utf-8') client_sk.send(msg1) client_sk.send(msg2) client_sk.send(msg3) def index(): msg = '这是{}页面rn'.format(path).encode('utf-8') client_sk.send(msg) # return msg def home(): msg = '这是{}页面'.format(path).encode('utf-8') client_sk.send(msg) def other(): msg = 'sorry {} not find'.format(path).encode('utf-8') client_sk.send(msg) #根据url中的内容返回不同页面 if path=='index': index() elif path=='home': home() else: other() #关闭客户端 client_sk.close()
看起来上面的代码还是要挨个写if判断,怎么办?我们还是有办法!
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(34) def index(path): msg = '这是{}页面rn'.format(path).encode('utf-8') return msg def home(path): msg = '这是{}页面'.format(path).encode('utf-8') return msg def error(path): msg = 'sorry {} not find'.format(path).encode('utf-8') return msg #定义一个url和执行函数对应关系的列表 path_lst = [ ('/index', index), ('/home', home), ] while True: client_sk,addrs=server_sk.accept() content=client_sk.recv(1024).decode('utf-8') print("客户端发来贺电:") print(content) #切出index con=content.split(' ') path=con[1] # 向页面返回内容 msg1 = 'HTTP/1.1 200 okrn'.encode('utf-8') msg2 = 'Content-Type:text/html;charset=utf-8rn'.encode('utf-8') msg3 = 'rn'.encode('utf-8') client_sk.send(msg1) client_sk.send(msg2) client_sk.send(msg3) # 2.定义一个变量来接受对应的函数名称 func = None # 3.变量列表,查收是否有对应的url for path_tup in path_lst: if path_tup[0] == path: func = path_tup[1] if func: msg = func(path) else: msg = error(path) client_sk.send(msg) #关闭客户端 client_sk.close()
完美解决了不同URL返回不同内容的问题。 但是我不想仅仅返回几个字符串,我想给浏览器返回完整的HTML内容,这又该怎么办呢?
没问题,不管是什么内容,最后都是转换成字节数据发送出去的。 我们可以打开HTML文件,读取出它内部的二进制数据,然后再发送给浏览器。
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(34) def index(path): #通过这里把对应界面返回 with open('index.html','rb') as f: msg=f.read() return msg def home(path): with open('home.html', 'rb') as f: msg = f.read() return msg def error(path): with open('error.html', 'rb') as f: msg = f.read() return msg path_lst = [ ('/index', index), ('/home', home), ] while True: client_sk,addrs=server_sk.accept() content=client_sk.recv(1024).decode('utf-8') print("客户端发来贺电:") print(content) #切出index con=content.split(' ') path=con[1] # 向页面返回内容 msg1 = 'HTTP/1.1 200 okrn'.encode('utf-8') msg2 = 'Content-Type:text/html;charset=utf-8rn'.encode('utf-8') msg3 = 'rn'.encode('utf-8') client_sk.send(msg1) client_sk.send(msg2) client_sk.send(msg3) func = None for path_tup in path_lst: if path_tup[0] == path: func = path_tup[1] if func: msg = func(path) else: msg = error(path) client_sk.send(msg) #关闭客户端 client_sk.close()
这网页能够显示出来了,但是都是静态的啊。页面的内容都不会变化的,我想要的是动态网站。
没问题,我也有办法解决。我选择使用字符串替换来实现这个需求。(这里使用时间戳来模拟动态的数据)
import socket server_sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM) server_sk.bind(('127.0.0.1',9999)) server_sk.listen(34) def index(path): #通过这里把对应界面返回 with open('index.html','r',encoding='utf-8') as f: msg=f.read() msg=msg.replace('xxoo',path).encode('utf-8') return msg def home(path): with open('home.html', 'r',encoding='utf-8') as f: msg = f.read() msg=msg.replace('xxoo', path).encode('utf-8') return msg def error(path): with open('error.html', 'r',encoding='utf-8') as f: msg = f.read() msg=msg.replace('xxoo', path).encode('utf-8') return msg path_lst = [ ('/index', index), ('/home', home), ] while True: client_sk,addrs=server_sk.accept() content=client_sk.recv(1024).decode('utf-8') print("客户端发来贺电:") print(content) #切出index con=content.split(' ') path=con[1] # 向页面返回内容 msg1 = 'HTTP/1.1 200 okrn'.encode('utf-8') msg2 = 'Content-Type:text/html;charset=utf-8rn'.encode('utf-8') msg3 = 'rn'.encode('utf-8') client_sk.send(msg1) client_sk.send(msg2) client_sk.send(msg3) func = None for path_tup in path_lst: if path_tup[0] == path: func = path_tup[1] if func: msg = func(path) else: msg = error(path) client_sk.send(msg) #关闭客户端 client_sk.close()
目录结构
总结
1.web框架的本质:socket 服务端 与浏览器的通讯。
2.socket 服务端功能可以划分为3部分:
- a.负责与浏览器收发消息(socket)在python中有专门的框架wsgiref/uWsgi/gunicorn...
- b.根据用户访问不同的路径执行不同的函数
- c.从HTML中读取出内容,并且完成字符串的替换
3.Python中 web 框架的分类:
- 按照2上面的功能分类
(1).框架自带a,b,c 功能 ----> Tornado
(2).框架自带b,c,使用第三方的a ---->Django
(3).框架自带b,使用第三方的a,c ---->Flask
-按照另一个维度划分
(1).Diango ,Tornado-->大而全(做一个网站用到的技术都有)
(2).其他 例如 Flask 轻量级只封装了核心功能。a部分和b、c 部分通讯需要遵守WSGI 协议。
最后
以上就是年轻小笼包为你收集整理的python框架是如何制作的什么是框架?WEB框架的本质的全部内容,希望文章能够帮你解决python框架是如何制作的什么是框架?WEB框架的本质所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复