不到100行写出一个完整的web框架

2023-05-16

本篇文章是为了后面的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()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不到100行写出一个完整的web框架 的相关文章

  • Netty Nio java 中的通信

    我想在 Netty nio 中创建一个具有两个客户端和一个服务器的通信系统 更具体地说 首先 我希望当两个客户端与服务器连接时从服务器发送消息 然后能够在两个客户端之间交换数据 我正在使用本示例提供的代码 https github com
  • 在脚本标签内工作的角度表达式

    如何在脚本标签内使用角度表达式 我对此很陌生并且需要帮助 这是我的 java 脚本代码的示例
  • 如何防止桌面浏览器(Chrome、Safari)缩放网页

    我尝试使用以下元视图端口标记来防止浏览器缩放 但这不起作用 我知道这是可能的 因为我的缩放在此网站上被阻止 未来主义 xyz http futurism xyz 该网站的视口标签是这样的
  • Safari 的“阅读器模式” - 开源解决方案? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Safari 有一个 阅读器模式 可以删除网站上除文本之外的所有内容 有谁知道提供相同功能的开源库 或
  • 给定数十亿个 URL,如何确定重复内容 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在一次编程面试中被问到这个问题 我在下面详细描述了这个问题 这是一个开放式问题 给定数十亿个 URL 深层链接 我如何对哪些 URL
  • VBA - 如何从网站下载.xls并将数据放入Excel文件

    我设法使用 VBA 达到准备从网络下载 Excel 文件的程度 但我无法弄清楚如何实际下载该文件并将其内容放入我正在使用的 Excel 文件中 有什么建议么 谢谢 这是到目前为止的代码 Sub GetData Dim IE As Inter
  • 为什么 [System.ComponentModel.ToolboxItem(false)] 默认出现在 Asp.net Web 服务中

    谁能告诉我为什么 System ComponentModel ToolboxItem false 是在Asp net Web服务中使用的吗 或许你可以在这里找到一些答案 NET API 浏览器 ToolboxItemAttribute 布尔
  • Azure Web 角色中的网站项目

    我正在研究一个新的 ASP Net 项目 我们希望将其托管在 Windows Azure Web 角色中 该项目的技术要求之一是利用 ASP Net 的完整预编译选项 不可更新 单页程序集 Web Site项目模型 与 ASP Net 相反
  • CSS3 与 JavaScript

    所以我试图在网页上创建一个动画 并试图找到一种使用 CSS3 来实现它的方法 但我对如何做到这一点感到非常困惑 我需要发生的是 当用户单击链接元素时 我希望 div 展开并填充特定于所单击的链接元素的内容 例如 当用户单击标题为 About
  • 我可以通过什么方式混合 jQuery 和 vanilla JavaScript

    我有一个用普通 JavaScript 编写的 Web 应用程序 我想用 jQuery 动画来增强它 并使用我在各种 jQuery 插件中找到的一些功能 例如上传 http www uploadify com 可以通过什么方式将 jQuery
  • java Web应用程序中的日期转换

    String date1 13 03 2014 16 56 46 AEDT SimpleDateFormat sdf new SimpleDateFormat dd MM yyyy HH mm ss z sdf setTimeZone Ti
  • ASP.net获取硬件信息

    如果我创建一个 ASP net 页面 我是否能够获取当前用户的 CPUID 和 BIOS 序列号 还是出于安全原因不允许这样做 我目前有一个获取这些值的 Visual Basic net 应用程序 我只是想知道是否可以在网页上执行相同的操作
  • 缩小 HTML、CSS 和 Javascript 是一个坏主意吗?

    维基百科定义缩小 http en wikipedia org wiki Minification 28programming 29 as 从源代码中删除所有不必要的字符而不改变其功能的过程 这些不必要的字符通常包括空格字符 换行符 注释 有
  • Bootstrap - 为反向行模式创建移动自适应

    我想用 Bootstrap 创建一个反向效果 第一行 左边是文字 右边是图像 第二行 左边是图片 右边是文字 第三行 左边是文字 右边是图片 第四行 左边是图片 右边是文字 而且这种情况一直持续下去 它在大型设备上看起来非常漂亮 但当它在设
  • 如何使我的网站兼容移动设备和平板电脑? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想让我现有的网站在手机 平板电脑上查看时自动调整 甚至在您在桌面上调整屏幕时自动调整 如果失败的话 如果太难 你有什么建议 我基本上
  • 是否可以下载网站的完整代码、HTML、CSS 和 JavaScript 文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 是否可以完全下载网站或查看其所有代码 例如 我知道您可以在浏览器中查看页面源代码 但是有没有办法下载所有网站代码 例如 HTML CSS
  • 开发工具在表达式上中断

    当给定的 Javascript 表达式为 true 时 我想暂停一切 我见过条件断点 但这对我不起作用 因为这需要首先在某处设置断点 或者首先基于某个标准 然后向其添加附加条件 相反 我想要的是能够在给定表达式为真时中断 无论在哪里 在 D
  • 在网站的一次导航中仅显示一次弹出窗口

    我有一个使用 Laravel 创建的网站 我希望用户第一次访问我的网站时能够看到弹出窗口 我的意思是第一次 用户访问我网站上的任何页面 这是第一次 访问网站上的一些链接页面 现在 这些页面访问不是第一次 在同一选项卡中打开 facebook
  • Angular 5 - ag-grid 18.0.1 - 边缘崩溃

    我一直在到处搜索 但无法找到与此相关的任何信息 很可能是因为 ag grid update 18 x 是新的 无论如何 似乎在将 ag grid 从 17 1 1 更新到 18 0 1 后 任何带有 ag grid 的页面最终都会导致 ED
  • 可靠的在线手册复制工具

    我经常需要在没有互联网的情况下开发项目 不幸的是 越来越多的程序不再有离线手册 在本地复制在线帮助的最佳方法是什么 HTTrack 网站复制器经常失败 哪个 Windows 工具最可靠 感谢你的建议 如果您有使用 HTTrack Websi

随机推荐