Python Web框架

所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

下面 我们开始自定义一个框架,逐步的完善它。

1、最基础,的web框架

import socket
sk=socket.socket(socket.AF_INET,socket.SOCK_STREAM)#创建tcp连接
sk.bind(('localhost',9900))#绑定本机和端口号
sk.listen()
while True:
    conn,addr=sk.accept()
    rt=conn.recv(1024)
    print(rt.decode('utf-8)
	
    conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
    conn.send(b'ok')
	#往页面上发送消息
    conn.send('王八蛋'.encode('utf-8'))
    conn.close()

控制台:
在这里插入图片描述网页上:
在这里插入图片描述

2、从上图可以看出网页上的文字乱码了,接下来我们解决乱码问题

import socket
sc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sc.bind(('127.0.0.1',9098))
sc.listen()
while True:
    conn,addr=sc.accept()
    rt=conn.recv(1024).decode('utf-8')
    print(rt)
    
    # 结局乱码
    msg1='http/1.1 200 ok \r\n'.encode('utf-8')
    msg2='Content-Type:text/html;charset=utf-8\r\n'.encode('utf-8')
    msg3='\r\n'.encode('utf-8')
    msg4='这是一首简单的小情歌'.encode('utf-8')

    #发送解决乱码的msg
    conn.send(msg1)
    conn.send(msg2)
    conn.send(msg3)
    conn.send(msg4)
    conn.send(b'<h1>hello</h1>' )
    conn.close()

页面(看乱码已解决):
在这里插入图片描述

3、获得路径

import socket
sc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sc.bind(('127.0.0.1',9098))
sc.listen()

while True:
    conn,addr=sc.accept()
    ret=conn.recv(1024)
    print(ret.decode('utf-8'))
    #这里我们把接收到的内容切割,直到我们得到想要的路径
    #首先以回车符+换行符切割,之后取第一个,再以空格切割取第二个
    data1=str(ret,encoding='utf-8').split('\r\n')[0].split(' ')[1]#ret这个返回值,如果在之前decode了,可以不用强转为字符串
    print(data1)
    
    #三种路径,分别是home,index,和未知
    if data1 =='/home':
        msg='这是{}页面'.format(data1).encode('utf-8')
    elif data1=='/index':
        msg='this is a{}  page'.format(data1).encode('utf-8')
    else:
        msg='sorry not find'.encode('utf-8')

    #解决乱码
    conn.send('http/1.1 200 ok\r\n'.encode('utf-8'))
    conn.send('Content-Type:text/html;charset=utf-8\r\n'.encode('utf-8'))
    conn.send('\r\n'.encode('utf-8'))
    conn.send(msg)

    conn.close()

获得的客户端的消息,也就是要切割的东西:
在这里插入图片描述
index路径下的网页
在这里插入图片描述
在这里插入图片描述
home路径下的网页
在这里插入图片描述
在这里插入图片描述
未知网页:
在这里插入图片描述
在这里插入图片描述

4、页面内容,上升为函数(必要的)

如果有很多很多路径要判断怎么办?难道要挨个写if判断?
当然不用,我们将所出现的可能的封装为一个一个的函数,通过切割出来的路径,来分别执行对应的 函数

import socket
sc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sc.bind(('127.0.0.1',9098))
sc.listen()

while True:
    conn,addr=sc.accept()
    ret=conn.recv(1024)
    print(ret.decode('utf-8'))
    #获得路径
    data=str(ret,encoding='utf-8').split('\r\n')[0]
    data1=data.split(' ')[1]
    print(data1)
    #三个函数,对应三个页面的内容
    def func1():
        return '这是{}页面'.format(data1).encode('utf-8')
    def func2():
        return 'this is a {}  page'.format(data1).encode('utf-8')
    def func3():
        return 'sorry not find'.encode('utf-8')


    #将三个函数放在列表中
    func=None
    ls=[('/index',func1),('/home',func2),('',func3)]
    #func赋值,
    for i in ls:
        if i[0]==data1:
            func=i[1]
            break
    #对应路径对应相应的函数
    if func:
        msg=func()
    else:
        msg=func3()

    #解决乱码问题
    conn.send('http/1.1 200 ok\r\n'.encode('utf-8'))
    conn.send('Content-Type:text/html;charset=utf-8\r\n'.encode('utf-8'))
    conn.send('\r\n'.encode('utf-8'))
    #显示对应路径
    conn.send(msg)


    conn.close()

结果和上图无差别
5、上面我们返回的是字符串,接下来我们返回html页面
写三个简单的html文件:
在这里插入图片描述
内容也很简单:
index:
在这里插入图片描述
home:
在这里插入图片描述
error:
在这里插入图片描述

import socket
sc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sc.bind(('127.0.0.1',9098))
sc.listen()

while True:
    conn,addr=sc.accept()
    ret=conn.recv(1024)
    print(ret.decode('utf-8'))
    #获得路径
    data=str(ret,encoding='utf-8').split('\r\n')[0]
    data1=data.split(' ')[1]
    print(data1)
    #三个函数,对应三个html的内容
    def func1():
        with open('index.html',mode='rb')as f:
            ret=f.read()
        return ret

    def func2():
        with open('home.html', mode='rb')as f:
            ret = f.read()
        return ret
    def func3():
        with open('error.html', mode='rb')as f:
            ret = f.read()
        return ret

    #将三个函数放在列表中
    func=None
    ls=[('/index',func1),('/home',func2),('',func3)]
    #func赋值,
    for i in ls:
        if i[0]==data1:
            func=i[1]
            break
    #对应路径对应相应的函数
    if func:
        msg=func()
    else:
        msg=func3()

    #解决乱码问题
    conn.send('http/1.1 200 ok\r\n'.encode('utf-8'))
    conn.send('Content-Type:text/html;charset=utf-8\r\n'.encode('utf-8'))
    conn.send('\r\n'.encode('utf-8'))
    #显示对应的html文件
    conn.send(msg)


    conn.close()

home路径下的
在这里插入图片描述
5、动态的页面,也就是代码中改变html中的内容

import socket

sc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sc.bind(('127.0.0.1',9098))
sc.listen()


# 三个函数,对应三个html的内容
def func1():
    with open('index.html', mode='r', encoding='utf-8')as f:
        ret = f.read()
        ret = ret.replace('xxoo', data1).encode('utf-8')#将index文件中的xxoo改为路径名字
    return ret


def func2():
    with open('home.html', mode='rb')as f:
        ret = f.read()
    return ret


def func3():
    with open('error.html', mode='rb')as f:
        ret = f.read()
    return ret

 #将三个函数放在列表中
func=None
ls=[('/index',func1),('/home',func2),('',func3)]
while True:
    conn,addr=sc.accept()
    ret=conn.recv(1024)
    # print(ret.decode('utf-8'))
    #获得路径
    data=str(ret,encoding='utf-8').split('\r\n')[0]
    data1=data.split(' ')[1]
    print(data1)


    #func赋值,
    for i in ls:
        if i[0]==data1:
            func=i[1]
            break
    #对应路径对应相应的函数
    if func:
        msg=func()
    else:
        msg=func3()

    #解决乱码问题
    conn.send('http/1.1 200 ok\r\n'.encode('utf-8'))
    conn.send('Content-Type:text/html;charset=utf-8\r\n'.encode('utf-8'))
    conn.send('\r\n'.encode('utf-8'))
    #显示对应的html文件
    conn.send(msg)


    conn.close()

结果对比:
在这里插入图片描述
and
在这里插入图片描述

总结
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 协议。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值