二、Web框架实现

作者:@skyflask
转载本文请注明出处:https://www.cnblogs.com/skyflask/p/9292101.html


目录

一、简单web(socket)
二、Web框架实现(Wsgiref)

一、简单web(socket)

在前一篇WEB框架概述一文中已经详细了解了:从浏览器键入一个URL到返回HTML内容的整个过程。说到底,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

最简单的Hello World程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import socket
 
HOST = ''
PORT = 80
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.bind((HOST, PORT))
listen_socket.listen(1)
connection, address = listen_socket.accept()
request = connection.recv(1024)
connection.sendall(b"""HTTP/1.1 200 OK
Content-type: text/html
  
<html>
    <body>
        <h1>Hello, World!</h1>
    </body>
</html>""")
connection.close()

 

这个代码接收简单的连接和一个客户端单一的请求,不管请求的 URL 是什么,它都会响应 HTTP 200(所以,这并不是一个真正意义上的 web 服务器)。Content-type:text/html 行代码的是 header 字段,header 用来提供请求或者响应的元信息。

我们从浏览器请求,可以得到如下结果:

这就是最简单的WEB应用。

如果要动态生成HTML,就需要把上述步骤自己来实现,每次定义发送和接受的内容。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。这个接口就是前面介绍过的WSGIWeb Server Gateway Interface。WSGI就是一种协议,描述web server(uwsgi)如何与web application(app)通信的规范。serverapplication的规范在PEP 3333中有具体描述。要实现WSGI协议,必须同时实现web server和web application,当前运行在WSGI协议之上的web框架有BottleFlaskDjango

当然,在python中,我们可以通过WSGIref来演示一个WEB框架的实现过程。

二、Web框架实现(Wsgiref)

Wsgiref库我们在前面已经有详细认识,所以这里不再介绍。

通过Wsgiref实现一个简单的WEB sever如下:

1
2
3
4
5
6
7
8
9
10
from wsgiref.simple_server import make_server
#1、符合WSGI规范的application
def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/html')])
    return [b'<h1>Hello, world!</h1>']
#2、Wsgiref定义启动server
httpd = make_server('', 80, application)
print('Serving HTTP on port 80...')
#3、开始监听HTTP请求:
httpd.serve_forever()

  用户访问结果如下:

我们从Wsgiref一文中了解到,environ其实是收集了一些环境变量(包括服务端的环境变量、客户端的请求信息以及wsgi信息),我们可以将其打印出来,添加代码:

for k,v in environ.items():
print k,v

  

 以上是实现了一个简单的请求和响应的过程,但是每次请求都是响应的固定不变的内容(hello world!)。现实当中,我们肯定希望是动态的内容,而且一般是通过请求不同的URL来返回不同的HTML内容。

所以,我们需要解决动态路由的问题。

从上面的基本信息中我们可以找到一个非常有用的信息:PATH_INFO。其实,这个变量就是代表了当前请求的URL。返回的内容我们可以很容易解决,通过函数返回不同的HTML内容就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#coding:utf-8
from wsgiref.simple_server import make_server
 
def user():
    return ['<h1>hello jay!</h1>']
 
def test():
    return ['<h1>Just  a test</h1>']
 
url_map = {'user':user,'test':test} #Flask里面就是通过url_map进行URL对象保存
 
def application(environ, start_response):
    path=environ['PATH_INFO'].split('/')[1]
    start_response('200 OK', [('Content-Type', 'text/html')])
 
    if path in url_map: #这里比较LowB了,Flask里面会把URL和视图函数进行绑定。
        return url_map[path]()
    else:
        return ["<h1>Page 404,not found!</h1>".encode("utf8")]
 
httpd = make_server('', 80, application)
print('Serving HTTP on port 80...')
# 开始监听HTTP请求:
httpd.serve_forever()

  

  这样,我们就把用户通过不同URL访问的内容进行了不同的响应,效果如下:

 当然,如果是真实环境下,我们会从数据库中获取数据,把固定的内容替换成可变的HTML内容,这样一个简单的web框架就成型了,是不是So easy?

posted @   skyflask  阅读(515)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示