写一个最简单的web框架

本篇文章是为了后面的Django做准备的,这是学习web框架的底层知识,没有直接用到socket,而是用Python自带的库wsgiref。
1、wsgiref模块
它就相当于是一个服务器,会帮我们做解析,内部已经封装好了socket等多项功能。

2、框架主要分为五部分
1)导入模块

from wsgiref.simple_server import make_server

2)自定义处理函数

def foo1(req):
    f=open("index1.html","rb")  # 读取文件
    data=f.read()
    return data

3)路由分发函数
即分发其他函数的一个函数,所有的要实现的功能都可以放在这里面传输到服务器,这样每一个路径都可以对应一个函数。

def router():
    url_patterns=[
        ("/login",login),
        ("/register",register),
        ("/Viewin", foo1),
        ("/Zoro", foo2),
        ("/show_time",show_time),
    ]
    return url_patterns

4)应用函数
框架本体,可以直接套用。一但有端口连接进入后,就会运行application函数,environ是wsgiref服务器处理传入的请求信息,是一个大字典,取值用键值对来取。

def application(environ, start_response):
    # 在application函数内,则需要作出响应操作

    #通过environ来取路径上输入的值
    print("path",environ["PATH_INFO"])
    path= environ["PATH_INFO"]

    # start_response设置响应头:状态码为200,状态码解析是OK,文本内容,文本格式...
    start_response('200 OK', [('Content-Type', 'text/html')])
    
	# return返回响应体
    return [b"<h1>Hello, web!</h1>"]

5)创建链接并监听HTTP请求
参数:IP地址,端口,应用函数
注意:这里的IP地址会默认获取本机的IP地址

# 创建链接
httpd = make_server('', 8080, application)

# 开始监听HTTP请求:
httpd.serve_forever()

3、前端代码body部分
1)show_time

<body>

<h1>时间:{{time}}</h1>
<!--自定义语法{{}}-->

</body>

2)login

<form action="http://192.168.43.247:8080/login" method="get">
    <p>用户:<input type="text" name="user"> </p>
    <p>密码:<input type="password" name="pwd"> </p>
    <p><input type="submit">提交</p>
</form>

3)index1

<h1>Hello ViewIn!</h1>

4)index2

<h1>Hello Zoro!</h1>

4、参考效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5、完整web框架

# 导入wsgiref模块(不会直接使用socket),
# 它相当于是一个服务器,会帮我们做解析,内部已经封装好了socket等多项功能
from wsgiref.simple_server import make_server
import time

# 自定义处理函数
def foo1(req):
    f=open("index1.html","rb")  # 读取文件
    data=f.read()
    return data

def foo2(req):
    f = open("index2.html", "rb")  # 读取文件
    data = f.read()
    return data

def login(req):
    # print(req)  #找到user和pwd所在的大的键为QUERY_STRING
    print(req["QUERY_STRING"])

    return b"Welcome to my web!"

def register(req):
    pass

def show_time(req):
    times=time.ctime()  # 获取时间的字符串
    f= open("show_time.html","rb")
    data= f.read().decode("utf8")

    # 自定义语法{{}},来找到我们需要的时间
    # 用变量times(准确的时间)去替换页面内的time
    data= data.replace("{{time}}",str(times))
    # 此处替换后的内容是字符串,因此需要转码一下
    return data.encode("utf8")


# 路由分发的函数:即分发其他函数的一个函数,所有的要实现的功能都可以放在这里面传输到服务器
# 这样每一个路径都可以对应一个函数
def router():
    url_patterns=[
        ("/login",login),
        ("/register",register),
        ("/Viewin", foo1),
        ("/Zoro", foo2),
        ("/show_time",show_time),
    ]
    return url_patterns

# 应用函数:一但有端口连接进入后,就会运行application函数
# environ是wsgiref服务器处理传入的请求信息,是一个大字典,取值用键值对来取
def application(environ, start_response):
    # 在application函数内,则需要作出响应操作

    #通过environ来取路径上输入的值
    print("path",environ["PATH_INFO"])
    path= environ["PATH_INFO"]

    # start_response设置响应头:状态码为200,状态码解析是OK,文本内容,文本格式...
    start_response('200 OK', [('Content-Type', 'text/html')])

    '''
    if path=="/Viewin":
        return[foo1()]
        # return[b"<h1>Hello ViewIn!</h1>"]  # 传入网页的应该是字节类型(二进制),并且最终应该包含在一个大字典里
    elif path=="/Zoro":
        return[foo2()]
        # return[b"<h1>Hello Zoro!</h1>"]
    '''

    # 接收路由分发函数
    url_patterns=router()
    func=None  # 用来装中间函数的
    # 遍历路由分发里的函数
    for item in url_patterns:
        # 如果遍历的对象和路径输入一致,则执行这个路径对应的函数
        if item[0]==path:
            func=item[1]
            break

    # 因为默认的None,所以需要判断一下是否为空
    if func:
        return[func(environ)]  # 执行中间函数,并将路径上获取的信息作为参数传入
    else:
        return [b"<h1>404</h1>"]

    # return返回响应体
    return [b"<h1>Hello, web!</h1>"]


# 参数:IP地址,端口,应用函数
# 注意:这里的IP地址会默认获取本机的IP地址
httpd = make_server('', 8080, application)

print('Serving HTTP on port 8080...')

# 开始监听HTTP请求:
httpd.serve_forever()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章