- 什么是web框架
- 框架,即farmework。特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演。
- 对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端
import socket
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 OK\r\n\r\n".encode("utf8"))
# client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))
#读取html文件
with open('index.html','rb') as f:
data = f.read()
client.send(data)
def main():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost',8001))
sock.listen(5)
while True:
connection, address = sock.accept()
handle_request(connection)
connection.close()
if __name__ == '__main__':
main()
- 最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回。
- 如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
- 正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口,让我们专心用Python编写Web业务。
- 这个接口就是WSGI:Web Server Gateway Interface。
- 1、最基础的,直接给浏览器返回固定值
from wsgiref.simple_server import make_server
def application(environ, start_response):
#通过enciron封装成一个所有请求信息的对象
#start_response 可以很方便的设置响应头
start_response('200 OK', [('Content-Type', 'text/html')])
print(environ)
return [b'<h1>Hello, web!</h1>']
#封装socket对象以及准备过程(socket,bind,listen)
httpd = make_server('localhost', 8080, application)
print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()
- 2、根据浏览器传的不同路径,返回不同内容
from wsgiref.simple_server import make_server
def f1(request): #request:形参,根据传入的environ获取请求参数,从而按不同逻辑处理
return [b'<h1>Hello, web!</h1>']
def f2(request):
return [b'<h1>Hello, book!</h1>']
def application(environ, start_response):
# print(environ['PATH_INFO'])
start_response('200 OK', [('Content-Type', 'text/html')])
path = environ['PATH_INFO']
if path == '/web':
return f1(environ)
# return [b'<h1>Hello, web!</h1>']
elif path == '/book':
return f2(environ)
# return [b'<h1>Hello, book!</h1>']
else:
return [b'<h1>404!</h1>']
httpd = make_server('localhost', 8080, application)
print('Serving HTTP on port 8000...')
# 开始监听HTTP请求:
httpd.serve_forever()
- 3、如上所示,如果有很多个路径,这样写就不适合了,于是我们通过循环的方式获取
from wsgiref.simple_server import make_server
import time
def router():
urlpath = (
('/book',f1),
('/web',f2),
('/curtime',f3),
)
return urlpath
def f1(request):
return [b'<h1>Hello, book!</h1>']
def f2(request):
return [b'<h1>Hello, web!</h1>']
def f3(request):
cur_time = time.ctime(time.time())
with open('cur_time.html','rb') as f:
data = f.read()
data = str(data,'utf8').replace('!curtime!',str(cur_time)) #返回当前时间
return [data.encode('utf8')]
def application(environ, start_response):
# print(environ['PATH_INFO'])
start_response('200 OK', [('Content-Type', 'text/html')])
path = environ['PATH_INFO']
urlpatterns = router()
func = None
for item in urlpatterns:
if item[0] == path:
func = item[1]
break
if func:
return func(environ)
else:
return ["<h1>404</h1>".encode("utf8")]
httpd = make_server('localhost', 8080, application)
print('Serving HTTP on port 8080...')
# 开始监听HTTP请求:
httpd.serve_forever()
//cur_time.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>current_time: !curtime!</h3>
</body>
</html>
- 伙计们,不知不觉我们自己已经写出一个web框架啦!