• 四十、手搭简易Web框架


    一 搭建socket服务端

    Web框架可以看做是一个功能强大的socket服务器,接下来就用socket搭建一个简单的Web框架。

    import socket
    
    server = socket.socket()
    
    server.bind(('127.0.0.1', 9000))
    
    server.listen(5)
    
    while True:
        sock, addr = server.accept()
        data = sock.recv(1024)
        print(data.decode('utf8'))
        sock.send(b'HTTP1.1 200 ok\r\n\r\nhello world!')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    现在就可以在浏览器中访问127.0.0.1:9000,接下来实现不同后缀返回不同内容。

    import socket
    
    server = socket.socket()
    
    server.bind(('127.0.0.1', 9000))
    
    server.listen(5)
    
    while True:
        sock, addr = server.accept()
        data = sock.recv(1024)
        # print(data.decode('utf8'))
        target_path = data.decode().split(' ')[1]
        if target_path == '/index/':
            sock.send(b'HTTP1.1 200 ok\r\n\r\nindex!')
        elif target_path == '/login/':
            sock.send(b'HTTP1.1 200 ok\r\n\r\nlogin!')
        else:
            sock.send(b'HTTP1.1 200 ok\r\n\r\n404 error!')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    上述代码的缺点有:

    1. socket代码过于重复。
    2. HTTP请求数据的处理方式不完善。

    二 基于wsgiref模块搭建web框架

    from wsgiref import simple_server
    
    
    def run(request, response):
        """
    
        :param request: 请求相关数据
        :param response:相应相关数据
        :return:返回给客户端的信息
        """
        response('200 ok', [])
    
        # print(request)
    
        url = request.get('PATH_INFO')
        print(url)
        if url == '/':
            return [b'welcome!']
        elif url == '/index/':
            return [b'index']
        elif url == '/login/':
            return [b'login']
        else:
            return [b'404 error']
    
    
    if __name__ == '__main__':
        sever = simple_server.make_server('127.0.0.1', 8080, run)
        sever.serve_forever()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    接下来减少if判断的代码。

    from wsgiref import simple_server
    
    
    def index(request):
        return 'index'
    
    
    def login(request):
        return 'login'
    
    
    def error(request):
        return 'error'
    
    
    urls = (
        ('/index', index),
        ('/login', login)
    )
    
    
    def run(request, response):
        """
    
        :param request: 请求相关数据
        :param response:相应相关数据
        :return:返回给客户端的信息
        """
        response('200 ok', [])
    
        # print(request)
        func_name = None
        url = request.get('PATH_INFO')
        for i in urls:
            if url == i[0]:
                func_name = i[1]
                break
        if func_name:
            res = func_name(request)
        else:
            res = error(request)
        return [res.encode('utf8')]
    
    
    if __name__ == '__main__':
        sever = simple_server.make_server('127.0.0.1', 8080, run)
        sever.serve_forever()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    根据py文件中功能的不同划分到不同的py文件(模块化)

    文件描述
    urls.py对应关系
    views.py功能函数
    start.py启动文件
    templates文件夹 存储html

    三 动静态网页

    动态网页:页面上展示的是后端返回的数据。
    静态网页:页面上的数据是写死的,想要修改只能修改源码。

    练习:在后端获取当前时间展示到前端页面

    def get_time(request):
        import time
        now = time.strftime('%Y-%m-%d %H:%M:%S')
        with open('html01.html', 'r', encoding='utf8') as f:
            date = f.read().replace('time', now)
        return date
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    jinja2模块

    jinja2模块可以让我们在HTML文件内使用类似于后端的语法来操作数据。它是一个第三方模块,使用前先安装。

    def get_dict(request):
        from jinja2 import Template
        user_dict = {"username": "jasper", "password": 123}
        with open('html02.html', 'r', encoding='utf8') as f:
            data = f.read()
        temp = Template(data)
        res = temp.render(data=user_dict)  # 将user_dict传给html
        return res
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    五 模板语法

    <table class="table table-bordered table-hover">
        <thead>
            <tr>
                <th>idth>
                <th>nameth>
                <th>passwordth>
            tr>
        thead>
        <tbody>
            {% for user in user_info %}
                <tr>
                    <td>{{ user.id }}td>
                    <td>{{ user.username }}td>
                    <td>{{ user.password }}td>
                tr>
            {% endfor %}
        tbody>
    table>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    Monaco-Editor 多人协作 编辑器
    【JavaSE】继承
    如何每天自动发送心灵鸡汤、正能量语录
    【ChatGPT】如何修复access denied you do not have access to chat.openai.com
    【瞎折腾】荣耀7X换脸手术,收获良多
    Flutter 使用 device_info_plus 遇到的问题
    LabVIEW样式检查表2
    解决cardano 交易“1.344798 Not enough funds for ”问题
    SpringMVC统一异常处理配置
    物联网安防-园区周界安防技术实现
  • 原文地址:https://blog.csdn.net/weixin_68531269/article/details/126605637