实现简单的web框架
实现简单的web框架
流程:
1 | 服务端启动 - - - 服务端等待请求 - - - 客户端访问 - - - 服务端响应请求 |
代码:
1 2 3 4 5 6 | from wsgiref.simple_server import make_server <br> #处理请求 def application(environ, start_response):<br> #响应头 start_response( '200 OK' , [( 'Content-Type' , 'text/html' )])<br> #响应内容 return [b '<h1>Hello, web!</h1>' ]<br><br> # 开始监听HTTP请求:httpd = make_server('', 8080, application) print('Serving HTTP on port 8000...') #永久启动服务<br>httpd.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 | 整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写, 我们只负责在更高层次上考虑如何响应请求就可以了。 application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。 Python内置了一个WSGI服务器,这个模块叫wsgiref application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数: / / environ:一个包含所有HTTP请求信息的 dict 对象; / / start_response:一个发送HTTP响应的函数。 在application()函数中,调用: start_response( '200 OK' , [( 'Content-Type' , 'text/html' )]) 就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。 start_response()函数接收两个参数,一个是HTTP响应码,一个是一组 list 表示的HTTP Header,每 个Header用一个包含两个 str 的 tuple 表示。 通常情况下,都应该把Content - Type 头发送给浏览器。其他很多常用的HTTP Header也应该发送。 然后,函数的返回值b '<h1>Hello, web!</h1>' 将作为HTTP响应的Body发送给浏览器。 有了WSGI,我们关心的就是如何从environ这个 dict 对象拿到HTTP请求信息,然后构造HTML, 通过start_response()发送Header,最后返回Body。 |
访问
用户输入不同的url,不同的url做不同的处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | from wsgiref.simple_server import make_server def application(environ, start_response): # 请求头 start_response( '200 OK' , [( 'Content-Type' , 'text/html' )]) print ( "path" ,environ[ 'PATH_INFO' ]) path = environ[ 'PATH_INFO' ] if path = = "/test" : return [b '<h1>Hello, test!</h1>' ] elif path = = "/alex" : return [b '<h1>Hello, alex!</h1>' ] else : return [b "404" ] httpd = make_server('', 8080 , application) print ( 'Serving HTTP on port 8000...' ) # 开始监听HTTP请求: httpd.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 | 用户每输入一个路径,我们用一个函数去处理。 from wsgiref.simple_server import make_server def foo1(): f = open ( "index1.html" , "rb" ) data = f.read() return data def foo2(): f = open ( "index2.html" , "rb" ) data = f.read() return data def application(environ, start_response): # 请求头 start_response( '200 OK' , [( 'Content-Type' , 'text/html' )]) print ( "path" ,environ[ 'PATH_INFO' ]) path = environ[ 'PATH_INFO' ] if path = = "/" : return [b "Hello Web" ] if path = = "/test" : return [foo1()] elif path = = "/alex" : return [foo2()] else : return [b "<a>404</a>" ] httpd = make_server('', 8080 , application) print ( 'Serving HTTP on port 8000...' ) # 开始监听HTTP请求: httpd.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 48 49 50 51 52 53 54 55 56 | 使用遍历来解决 from wsgiref.simple_server import make_server def login(req): print (req[ 'QUERY_STRING' ]) return b 'welcome' def signup(req): pass 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 route(): url_patterns = [( "/login" ,login), ( "/signup" ,signup), ( "/test" ,foo1), ( "/alex" ,foo2)] return url_patterns def application(environ, start_response): # 请求头 start_response( '200 OK' , [( 'Content-Type' , 'text/html' )]) print ( "path" ,environ[ 'PATH_INFO' ]) path = environ[ 'PATH_INFO' ]<br> #初始化 func = None <br> #获得url路由表 url_list = route()<br> #遍历 for url in url_list: if url[ 0 ] = = path: func = url[ 1 ] print (func) break <br> #如果是路由表里的url则执行相应函数 if func: return [func(environ)] else : return [ "<h1>404</h1>" .encode( "utf8" )] httpd = make_server('', 8080 , application) print ( 'Serving HTTP on port 8000...' ) # 开始监听HTTP请求: httpd.serve_forever() |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?