一、Web框架本质
-
所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端
二、Web框架功能
-
socket收发消息 —— wsgiref(测试)、uwsgi(线上)
-
根据不同的路径返回不同的字符串
-
返回动态页面(字符串的替换)—— jinja2
三、Web框架种类
-
django
-
根据不同的路径返回不同的字符串
-
返回动态页面(字符串的替换)
-
-
flask
-
根据不同的路径返回不同的字符串
-
-
tornado
-
socket收发消息
-
根据不同的路径返回不同的字符串
-
返回动态页面(字符串的替换)
-
四、自定义web框架
-
简单示例:socket服务端
import socket # 创建一个socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen(5) # 等待连接 while True: conn, addr = sk.accept() # 接收数据 data= conn.recv(1024) print(data) # 返回数据 conn.send(b'HTTP/1.1 200 OK <h1>ok!</h1>') # 断开连接 conn.close()
-
根据不同路径返回不同的内容(普通版)
import socket # 创建一个socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen(5) # 等待连接 while True: conn, addr = sk.accept() # 接收数据 data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] conn.send(b'HTTP/1.1 200 OK ') if url == '/index/': # 返回数据 conn.send(b'<h1>index!</h1>') elif url == '/home/': conn.send(b'<h1>home!</h1>') else: conn.send(b'<h1>404 not found!</h1>') # 断开连接 conn.close()
import socket # 创建一个socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen(5) # 函数 def index(url): ret = '<h1>index!</h1>({})'.format(url) return ret.encode('utf-8') def home(url): ret = '<h1>home!</h1>({})'.format(url) return ret.encode('utf-8') # 等待连接 while True: conn, addr = sk.accept() # 接收数据 data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] conn.send(b'HTTP/1.1 200 OK ') if url == '/index/': # 返回数据 ret = index(url) elif url == '/home/': ret = home(url) else: ret = b'<h1>404 not found!</h1>' conn.send(ret) # 断开连接 conn.close()
import socket # 创建一个socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen(5) # 函数 def index(url): ret = '<h1>index!</h1>({})'.format(url) return ret.encode('utf-8') def home(url): ret = '<h1>home!</h1>({})'.format(url) return ret.encode('utf-8') # 定义一个list1和实际要执行的函数的对应关系 list1 = [ ('/index/', index), ('/home/', home), ] # 等待连接 while True: conn, addr = sk.accept() # 接收数据 data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] conn.send(b'HTTP/1.1 200 OK ') func = None for i in list1: if url == i[0]: func = i[1] break if func: ret = func(url) else: ret = b'<h1>404 not found!</h1>' conn.send(ret) # 断开连接 conn.close()
import socket # 创建一个socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen(5) # 函数 def index(url): with open('index.html','rb') as f: ret = f.read() return ret def home(url): ret = '<h1>home!</h1>({})'.format(url) return ret.encode('utf-8') # 定义一个list1和实际要执行的函数的对应关系 list1 = [ ('/index/', index), ('/home/', home), ] # 等待连接 while True: conn, addr = sk.accept() # 接收数据 data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] conn.send(b'HTTP/1.1 200 OK ') func = None for i in list1: if url == i[0]: func = i[1] break if func: ret = func(url) else: ret = b'<h1>404 not found!</h1>' conn.send(ret) # 断开连接 conn.close()
import socket import time # 创建一个socket对象 sk = socket.socket() # 绑定IP和端口 sk.bind(('127.0.0.1', 8000)) # 监听 sk.listen(5) # 函数 def index(url): with open('index.html', 'rb') as f: ret = f.read() return ret def home(url): ret = '<h1>home!</h1>({})'.format(url) return ret.encode('utf-8') def timer(url): now = time.strftime('%H:%M:%S') with open('time.html','r',encoding='utf-8') as f: data = f.read() data = data.replace('xxtimexx',now) return data.encode('utf-8') # 定义一个list1和实际要执行的函数的对应关系 list1 = [ ('/index/', index), ('/home/', home), ('/time/', timer), ] # 等待连接 while True: conn, addr = sk.accept() # 接收数据 data = conn.recv(1024) data = data.decode('utf-8') url = data.split()[1] conn.send(b'HTTP/1.1 200 OK ') func = None for i in list1: if url == i[0]: func = i[1] break if func: ret = func(url) else: ret = b'<h1>404 not found!</h1>' conn.send(ret) # 断开连接 conn.close() 补充:time.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>当前时间是:@@time@@</h1> </body> </html>
五、wsgiref
-
常用的WSGI服务器有uWSGI、Gunicorn
-
Python标准库提供的独立WSGI服务器叫wsgiref,Django开发环境用的就是这个模块来做服务器
-
-
简单示例:
""" 根据URL中不同的路径返回不同的内容--函数进阶版 返回HTML页面 让网页动态起来 wsgiref模块版 """ from wsgiref.simple_server import make_server # 将返回不同的内容部分封装成函数 def index(url): # 读取index.html页面的内容 with open("index.html", "r", encoding="utf8") as f: s = f.read() # 返回字节数据 return bytes(s, encoding="utf8") def home(url): with open("home.html", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8") def timer(url): import time with open("time.html", "r", encoding="utf8") as f: s = f.read() s = s.replace('@@time@@', time.strftime("%Y-%m-%d %H:%M:%S")) return bytes(s, encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/", index), ("/home/", home), ("/time/", timer), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" return [response, ] if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
六、jinja2
-
-
下载jinja2:pip install jinja2
-
-
示例:
from wsgiref.simple_server import make_server from jinja2 import Template def index(url): # 读取HTML文件内容 with open("index2.html", "r", encoding="utf8") as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({'name': 'alex', 'hobby_list': ['抽烟', '喝酒', '烫头']}) # 把数据填充到模板中 return bytes(ret, encoding="utf8") def home(url): with open("home.html", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8") # 定义一个url和实际要执行的函数的对应关系 list1 = [ ("/index/", index), ("/home/", home), ] def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" return [response, ] if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <h1>姓名:{{name}}</h1> <h1>爱好:</h1> <ul> {% for hobby in hobby_list %} <li>{{hobby}}</li> {% endfor %} </ul> </body> </html>