• 四十、手搭简易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
  • 相关阅读:
    SQL查询优化---单表使用索引及常见索引失效优化
    21.4 Python 使用GeoIP2地图定位
    react循环实现及key的作用
    (附源码)springboot物流配货管理系统 毕业设计 250858
    C语言和C++的区别
    Java | Leetcode Java题解之第130题被围绕的区域
    数据结构刷题——图论
    Linux篇 五、Ubuntu与Linux板卡建立NFS服务
    【Dynamic-datasource】Springboot多数据源整合
    人工神经网络建模步骤,神经网络设计与实现
  • 原文地址:https://blog.csdn.net/weixin_68531269/article/details/126605637