赞
踩
web框架是一个为web服务器提供服务的应用程序,专门负责处理用户的动态资源请求.
静态资源: 资源的内容是固定不变的.
动态资源: 资源的内容是动态变化, 数据是从数据库获取的.
- 静态 web 服务器 使用 tcp 传输数据
- 1. 导包 socket
- 2. 创建一个 socket 对象, socket.socket()
- 端口复用(可选的)
- 3. 绑定 socket对象.bind((ip, 端口))
- 4. 监听 socket对象.listen()
- 5. 等待连接 socket对象.accept()---> 阻塞等待客户端连接,返回一个新的 socket 对象
- 6. 接收信息(请求报文) recv
- 7. 发送信息(响应报文) send
- 8. 关闭套接字 close()
- ------------------------------------------
- web 服务器的工作流程
- 1. 在浏览器输入 URL 网址
- 2. 浏览器会访问 DNS 服务器, 做 DNS 解析, 将域名对应的 ip 进行返回
- 3. 和服务器建立连接(三次握手)
- 4. 发送请求报文
- 5. web 服务器接收浏览器发送报文, 解析报文, 判断请求的资源是静态资源还是动态资源
- 6. 如果是静态资源, web 服务器自己处理,将内容返回
- 7. 如果是动态资源, 需要将请求交给 web 框架处理
- 8. web 框架根据 web 服务器发送的请求, 从模板库中读取需要的模版文件, 同时还需要中数据库中查询需要的数据, 将数据和模版文件进行整合,组成完整的数据
- 9. web 框架将整理后的数据和处理结果发送给 web 服务器
- 10. web 服务器根据 web 框架发送内容,组成响应报文,发送给浏览器
- 11. 浏览器将资源进行整合, 显示内容
- ---5 7 8 9 10 写代码实现---
1. 找到之前书写的静态 web 服务器的代码, 作为 web 服务器使用
- import socket
- import threading
-
- class HTTPWebServer(object):
- def __init__(self):
- # 1. 创建 socket
- server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- # 设置端口复用
- server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
- # 2. 绑定端口和 ip
- server_socket.bind(('', 8080))
- # 3. 设置监听
- server_socket.listen(128)
- self.server_socket = server_socket # 将这个 socket 作为实例属性
-
- def __del__(self): # 对象销毁的时候调用 close() 方法
- self.server_socket.close()
-
- @staticmethod
- def __handle_client_request(new_soc, client_ip_port):
- # 5. 接收信息(HTTP 请求报文)
- buf = new_soc.recv(4096) # 一次性报文
- if buf:
- # 打印请求报文
- # print(buf.decode())
- buf = buf.decode()
- # 6. 发送信息(HTTP 响应报文)
- # 响应行 协议的版本 状态码 状态描述
- response_line = "HTTP/1.1 200 OKrn"
- # 响应头
- response_header = "Server:PYrnName:py40rn"
- # 空行(rn)
- # 响应体, 文件的内容, 读取文件,将文件的内容作为响应体发送
- file_name = buf.split(' ', 2)[1]
- print(f"请求的资源为{file_name}")
- # 访问的资源是 / ---> index.html
- if file_name == '/':
- file_name = '/index.html'
-
- try:
- with open('static' + file_name, 'rb') as f: # rb, 读取出来的直接是 bytes
- data = f.read()
- except FileNotFoundError:
- with open('static/error.html', 'rb') as f:
- data = f.read()
- # 如果文件不存在, 修改响应行的状态码
- response_line = "HTTP/1.1 404 Not Foundrn"
-
- response = (response_line + response_header + 'rn').encode() + data
- new_soc.send(response)
- else:
- print(f"{client_ip_port} 断开连接...")
- # 7. 关闭连接
- new_soc.close()
-
- def start(self):
- # 4. 等待连接
- print('服务已启动,端口为 8080, 等待连接....')
- while True:
- new_socket, ip_port = self.server_socket.accept()
- print(f"{ip_port} 建立连接......")
- # 用户连接之后,创建一个线程
- sub_thread = threading.Thread(target=self.__handle_client_request, args=(new_socket, ip_port))
- sub_thread.start()
-
- if __name__ == '__main__':
- # 创建对象
- web = HTTPWebServer()
- web.start() # 启动服务器
2. 将 static 文件和 template 文件放到当天的代码目录中
3. 启动 web 服务器, 访问之前的静态页面, 能够正常访问
4. 修改 web 服务器的代码
判断一个资源是不是动态资源, 只需要判断资源是不是以 .html
结尾 字符串.endswith()
- # 此时获取到文件的资源路径,需要判断是静态资源还是动态资源
- if file_name.endswith('.html'):
- """动态资源, 交给框架处理"""
- # 思考,框架如何知道请求的是哪个页面 ---> 函数传参
- # 一般的方法, 将需要传递的数据组成字典传递
- # 好处: 可以传递多个数据
- env = {
- 'filename': file_name,
- # 还可以传递其他参数,目前不需要
- }
- status, header, file_data = framework.handle_request(env)
- response_line = "HTTP/1.1 %srn" % status
- response_header = header
- data = file_data.encode()
- else:
- """静态资源,web 服务器直接自己处理"""
- try:
- with open('static' + file_name, 'rb') as f: # rb, 读取出来的直接是 bytes
- data = f.read()
- except FileNotFoundError:
- with open('static/error.html', 'rb') as f:
- data = f.read()
- # 如果文件不存在, 修改响应行的状态码
- response_line = "HTTP/1.1 404 Not Foundrn"
web框架程序(framework.py)代码:
- """miniweb框架,负责处理动态资源请求"""
- import time
-
- # 获取首页数据
- def index():
- # 响应状态
- status = "200 OK";
- # 响应头
- response_header = [("Server", "PWS2.0")]
- # 处理后的数据
- data = time.ctime()
-
- return status, response_header, data
-
- # 没有找到动态资源
- def not_found():
- # 响应状态
- status = "404 Not Found";
- # 响应头
- response_header = [("Server", "PWS2.0")]
- # 处理后的数据
- data = "not found"
-
- return status, response_header, data
-
- # 处理动态资源请求
- def handle_request(env):
- # 获取动态请求资源路径
- request_path = env["filename"]
- print("接收到的动态资源请求:", request_path)
-
- if request_path == "/index.html":
- # 获取首页数据
- result = index()
- return result
- else:
- # 没有找到动态资源
- result = not_found()
- return result
路由: 请求的 URL 到到处理的函数之间的关系
- # 定义路由列表, 在列表中保存所有的请求资源和处理函数的对应关系(Django)
- route_list = [
- ('/index.html', index), # 函数地址的引用, 不能加括号的
- ('/center.html', center)
- ]
-
- def handle_request(env):
- """处理动态资源请求"""
- # 1. 获取web 服务器传递的参数
- file_name = env['filename'] # 通过字典的key 取值
- print(f'接收到要处理的动态资源是: {file_name}')
- # 遍历路由列表, 查找需要请求的资源是否在路由列表中
- for route in route_list:
- if file_name == route[0]:
- func = route[1] # func 是一个函数
- return func() # return route[1]()
- else:
- return not_found()
- route_list = []
-
- def my_route(filename):
- # 定义装饰器
- def decorator(fn):
- # 添加路由
- # route_list.append((filename, fn))
-
- def inner():
- return fn()
-
- route_list.append((filename, inner))
- return inner
- return decorator
-
- @my_route('/index.html')
- def index(): # 视图函数
- """专门用来处理首页数据的"""
- # 1. 从模板库读取 html 页面
- with open('template/index.html', 'r') as f:
- file_data = f.read()
stock_db.sql
复制到 Ubuntu 桌面中mysql -uroot -pmysql
create database stock_db charset=utf8;
use stock_db
source ~/Desktop/stock_db.sql
- # 获取首页数据
- @route("/index.html")
- def index():
- # 响应状态
- status = "200 OK";
- # 响应头
- response_header = [("Server", "PWS2.0")]
-
- # 打开模板文件,读取数据
- with open("template/index.html", "r") as file:
- file_data = file.read()
-
- # 处理后的数据, 从数据库查询
- conn = pymysql.connect(host="localhost",
- port=3306,
- user="root",
- password="mysql",
- database="stock_db",
- charset="utf8")
-
- # 获取游标
- cursor = conn.cursor()
- # 查询sql语句
- sql = "select * from info;"
- # 执行sql
- cursor.execute(sql)
- # 获取结果集
- result = cursor.fetchall()
- print(result)
-
- data = ""
- for row in result:
- data += '''<tr>
- <td>%s</td>
- <td>%s</td>
- <td>%s</td>
- <td>%s</td>
- <td>%s</td>
- <td>%s</td>
- <td>%s</td>
- <td>%s</td>
- <td><input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="000007"></td>
- </tr>''' % row
-
- # 替换模板文件中的模板遍历
- result = file_data.replace("{%content%}", data)
-
- return status, response_header, result
前后端分离
- # 个人中心数据接口开发
- @route("/center_data.html")
- def center_data():
- # 响应状态
- status = "200 OK";
- # 响应头
- response_header = [("Server", "PWS2.0"), ("Content-Type", "text/html;charset=utf-8")]
- conn = pymysql.connect(host="localhost",
- port=3306,
- user="root",
- password="mysql",
- database="stock_db",
- charset="utf8")
-
- # 获取游标
- cursor = conn.cursor()
- # 查询sql语句
- sql = '''select i.code, i.short, i.chg,
- i.turnover, i.price, i.highs, f.note_info
- from info as i inner join focus as f on i.id = f.info_id;'''
- # 执行sql
- cursor.execute(sql)
- # 获取结果集
- result = cursor.fetchall()
- # 关闭游标
- cursor.close()
- # 关闭数据库连接
- conn.close()
- # 个人中心数据列表
- center_data_list = list()
- # 遍历每一行数据转成字典
- for row in result:
- # 创建空的字典
- center_dict = dict()
- center_dict["code"] = row[0]
- center_dict["short"] = row[1]
- center_dict["chg"] = row[2]
- center_dict["turnover"] = row[3]
- center_dict["price"] = str(row[4])
- center_dict["highs"] = str(row[5])
- center_dict["note_info"] = row[6]
- # 添加每个字典信息
- center_data_list.append(center_dict)
-
- # 把列表字典转成json字符串, 并在控制台显示
- json_str = json.dumps(center_data_list,ensure_ascii=False)
- print(json_str)
- return status, response_header, json_str
代码说明:
- // 发送ajax请求获取个人中心页面数据
- $.get("center_data.html", function (data) {
-
- var data_array = data;
-
- // 获取table标签对象
- var $table = $(".table")
- for(var i = 0; i < data_array.length; i++){
- // 获取每一条对象
- var center_obj = data_array[i];
- var row_html = '<tr>' +
- '<td>'+ center_obj.code +'</td>' +
- '<td>'+ center_obj.short +'</td>' +
- '<td>'+ center_obj.chg +'</td>' +
- '<td>'+ center_obj.turnover +'</td>' +
- '<td>'+ center_obj.price +'</td>' +
- '<td>'+ center_obj.highs +'</td>' +
- '<td>'+ center_obj.note_info +'</td>' +
- '<td><a type="button" class="btn btn-default btn-xs" href="/update/000007.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a></td><td><input type="button" value="删除" id="toDel" name="toDel" systemidvaule="000007"></td></tr>';
- // 为table标签添加每一行组装的html数据
- $table.append(row_html);
- }
-
- }, "json");
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。