Django之web本质
Django之web本质
Web的本质,是基于socket玩的。
在我们上网的过程中,一个访问请求是如何工作的。
Web的框架:
网络的连接都是基于Socket
在连接中有TCP/UDP 和HTTP协议
HTTP协议是:无状态,短连接。(HTTP协议的访问状态是发送请求连接一次,返回请求结果数据一次,就断开连接)
无状态体现在同样的请求者第二次发请求来,服务端不认识它。
TCP:不断开,安全,不丢包,慢
UDP:易丢包,快
Web的工作流程:
浏览器端(Socket客户端)
2、域名或DNS正反解析出的IP,在浏览器中输入。 在socket端创建Socket对象 Socket.socket() 在创建连接 Socket.connet(("IP",端口)) 在发送连接请求 socket.send("我想请求数据") 5、接收响应的数据 6、连接断开,完成一个HTTP请求
网站服务端(Socket服务端)
1、监听自己网站的IP和域名,while 循环监听 while True: 等待用户连接 3、接收用户的连接请求("我想请求数据") 4、响应用户的连接,给用户返回响应的数据("好") 断开连接,等待下一个用户的连接请求
socket的服务端:
web的最本质最基本简化的流程。
1 import socket 2 3 Socket = socket.socket() 4 # 创建Socket对象 5 6 Socket.bind(("127.0.0.1",8080)) 7 # 绑定IP和端口 8 9 Socket.listen(5) 10 # 监听等待5个连接 11 12 while True: 13 conn, addr = Socket.accept() 14 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 15 16 data = conn.recv(8096) 17 # 获取数据 18 19 print(data) 20 # 打印一下data的获取数据的结果 21 22 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 23 # 响应头 24 25 conn.send(b'123') 26 # 响应的返回数据,响应体 27 28 conn.close() 29 # 断开连接
HTTP协议:发送的数据和响应的数据是有相互的规则的,规则遵循HTTP协议。
发送(Request):
GET请求:
GET请求头:
1 数据在请求头的url中。在GET / /HTTP1.1 的第一个/后,也就是请求体(请求体Request Bodys) 2 3 GET / HTTP/1.1 4 Host: 127.0.0.1:8080 5 Connection: keep-alive 6 Cache-Control: max-age=0 7 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 8 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36 9 HTTPS: 1 10 Accept-Encoding: gzip, deflate, sdch 11 Accept-Language: zh-CN,zh;q=0.8 12 Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni 13 14 15 请求体部分
GET请求体:数据在url中。
1 GET的请求体在GET / HTTP/1.1中的第一个 "/" 后。 2 例如: 3 GET /index?p=123 HTTP/1.1 4 其中,index是url,这没错,but,p=123就是请求体。
POST请求:
POST请求头:
1 POST /index HTTP/1.1 2 Host: 127.0.0.1:8080 3 Connection: keep-alive 4 Cache-Control: max-age=0 5 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 6 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36 7 HTTPS: 1 8 Accept-Encoding: gzip, deflate, sdch 9 Accept-Language: zh-CN,zh;q=0.8 10 Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni 11 12 13 请求体部分
POST请求体:
1 POST /index HTTP/1.1 2 Host: 127.0.0.1:8080 3 Connection: keep-alive 4 Cache-Control: max-age=0 5 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 6 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36 7 HTTPS: 1 8 Accept-Encoding: gzip, deflate, sdch 9 Accept-Language: zh-CN,zh;q=0.8 10 Cookie: csrftoken=hNmu2JOtntGMN0hSRSPmMQk2newEb3o8zb6pXW5Cc3m54IaA5VlTkUvqWsFezpni 11 12 13 p=123 #POST请求体内容
响应(Response):
响应头:
在响应体中,要注意一个Status Code的状态码,应为200 OK 响应头是在Response Headers中。 响应头的数据: Cache-Control:public, max-age=15 Connection:keep-alive Content-Encoding:gzip Content-Type:text/html; charset=utf-8 Date:Wed, 14 Jun 2017 01:21:17 GMT Expires:Wed, 14 Jun 2017 01:21:33 GMT Last-Modified:Wed, 14 Jun 2017 01:21:03 GMT Transfer-Encoding:chunked Vary:Accept-Encoding X-Frame-Options:SAMEORIGIN X-UA-Compatible:IE=10
响应体:就是看到的前端页面,页面效果是浏览器解析的而已的啦。
优化socket服务端流程,丰富功能:MK2
分化url,不同的url,显示不同的内容。
1 import socket 2 3 Socket = socket.socket() 4 # 创建Socket对象 5 Socket.bind(("127.0.0.1",8080)) 6 # 绑定IP和端口 7 Socket.listen(5) 8 # 监听的次数 9 while True: 10 #监听循环 11 conn, addr = Socket.accept() 12 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 13 data = conn.recv(8096) 14 # 获取数据 15 print(data) 16 #打印拿到的请求数据 17 data = str(data,encoding="utf-8") 18 #将data的数据类型,由byte类型转换成str类型。并编码为utf-8。 19 Headers,Bodys = data.split("\r\n\r\n") 20 #将data数据用split以"\r\n\r\n"分割成请求头和请求体 21 temp_list = Headers.split("\r\n") 22 #将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同 23 method,url,protocal = temp_list[0].split(" ") 24 #将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url 25 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 26 # 响应头 27 if url == "/XXX": 28 conn.send(b"asfafafas") 29 elif url == "/BBB": 30 conn.send(b"qqqqqq") 31 else: 32 conn.send(b"404 not found") 33 conn.close()
在获取的用户数据后,转换成数据类型,比如字符串,操作如下:
data拿到的一般都是字节byte类型的数据
data = str(data,encoding = "utf-8")
即可将byte的数据类型,直接转换成字符串str的数据类型。
在拿取请求头是,是根据\r\n 来分割开请求头和请求体的。
1 headers,bodys = data.split("\r\n\r\n") 2 #这样可以将请求头和请求体分来。 3 4 #在请求头中在进行分割: 5 headers.split("\r\n")
对请求头再进一步的分割,可以将headers放在列表里,进行操作。这个的url是请求的url
1 temp_list = Headers.split("\r\n") 2 #将Headers放进列表 3 4 #在对请求头的第一行数据进行单独的操作,因为第一行数据不同。 5 #GET / /HTTP1.1\n 6 #定义GET为method,/后的请求体为url,是请求的url,/HTTP是协议protocal 7 method,url,protocal = temp_list[0].split(" ") 8 #根据空格分割。
MK3,将url抽离出,可单独操作每一个url。
1 # Socket服务端 2 import socket 3 4 def index(request): 5 return b'index' 6 7 def func2(request): 8 return b'func2' 9 10 # 定义一个列表,里面存有url和url对应的函数名 11 Routers = [ 12 ("/index",index), #url 为XXX时,执行func1函数 13 ("/SSS",func2), #url 为SSS时,执行func2函数 14 ] 15 16 def run(): 17 """ 18 Socket服务端响应 19 :return: 20 """ 21 Socket = socket.socket() 22 # 创建Socket对象 23 Socket.bind(("127.0.0.1",8080)) 24 # 绑定IP和端口 25 Socket.listen(5) 26 # 监听的次数 27 while True: 28 #监听循环 29 conn, addr = Socket.accept() 30 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 31 data = conn.recv(8096) 32 # 获取数据 33 print(data) 34 #打印拿到的请求数据 35 data = str(data,encoding="utf-8") 36 #将data的数据类型,由byte类型转换成str类型。并编码为utf-8。 37 Headers,Bodys = data.split("\r\n\r\n") 38 #将data数据用split以"\r\n\r\n"分割成请求头和请求体 39 temp_list = Headers.split("\r\n") 40 #将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同 41 method,url,protocal = temp_list[0].split(" ") 42 #将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url 43 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 44 # 响应头 45 func_name = None 46 #定义一个func_name,用于赋值item的func函数 47 for item in Routers: 48 #循环遍历Routers列表里的url。 49 if item[0] == url: 50 #取出url进行判断 51 func_name = item[1] 52 #如果匹配到func指定的函数 53 break 54 if func_name: 55 #如果func_name=True,存在,就拿func_name 的值 56 response = func_name(data) 57 else: 58 response = b"404 Not Found" 59 conn.send(response) 60 #发送Response的值给作为响应体 61 conn.close() 62 63 64 if __name__ == "__main__": 65 run()
结果:
--->--->
MK4 优化函数的功能,丰富页面的内容:静态网站
index页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>index</title> 6 </head> 7 <body> 8 <h1>Login</h1> 9 <form> 10 <p><input type="text" placeholder="Username"></p> 11 <p><input type="password" placeholder="Password"></p> 12 </form> 13 </body> 14 </html>
func2页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>article</title> 6 </head> 7 <body> 8 <table border='1'> 9 <thead> 10 <tr> 11 <th>ID</th> 12 <th>Username</th> 13 <th>Email</th> 14 </tr> 15 </thead> 16 <tbody> 17 <tr> 18 <th>0001</th> 19 <th>George</th> 20 <th>George@G.com</th> 21 </tr> 22 </tbody> 23 </table> 24 </body> 25 </html>
socket端代码:
1 # Socket服务端 2 import socket 3 4 def index(request): 5 """ 6 处理用户请求,并返回响应数据 7 :param request: 用户请求的所有信息 8 :return: 9 """ 10 f = open("index.html","rb") 11 data = f.read() 12 f.close() 13 return data 14 15 def func2(request): 16 """ 17 处理用户请求,并返回响应数据 18 :param request: 用户请求的所有信息 19 :return: 20 """ 21 f = open("article.html","rb") 22 data = f.read() 23 f.close() 24 return data 25 26 27 # 定义一个列表,里面存有url和url对应的函数名 28 Routers = [ 29 ("/index",index), #url 为XXX时,执行func1函数 30 ("/SSS",func2), #url 为SSS时,执行func2函数 31 ] 32 33 def run(): 34 """ 35 Socket服务端响应 36 :return: 37 """ 38 Socket = socket.socket() 39 # 创建Socket对象 40 Socket.bind(("127.0.0.1",8080)) 41 # 绑定IP和端口 42 Socket.listen(5) 43 # 监听的次数 44 while True: 45 #监听循环 46 conn, addr = Socket.accept() 47 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 48 data = conn.recv(8096) 49 # 获取数据 50 print(data) 51 #打印拿到的请求数据 52 data = str(data,encoding="utf-8") 53 #将data的数据类型,由byte类型转换成str类型。并编码为utf-8。 54 Headers,Bodys = data.split("\r\n\r\n") 55 #将data数据用split以"\r\n\r\n"分割成请求头和请求体 56 temp_list = Headers.split("\r\n") 57 #将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同 58 method,url,protocal = temp_list[0].split(" ") 59 #将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url 60 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 61 # 响应头 62 func_name = None 63 #定义一个func_name,用于赋值item的func函数 64 for item in Routers: 65 #循环遍历Routers列表里的url。 66 if item[0] == url: 67 #取出url进行判断 68 func_name = item[1] 69 #如果匹配到func指定的函数 70 break 71 if func_name: 72 #如果func_name=True,存在,就拿func_name 的值 73 response = func_name(data) 74 else: 75 response = b"404 Not Found" 76 conn.send(response) 77 #发送Response的值给作为响应体 78 conn.close() 79 80 81 if __name__ == "__main__": 82 run()
结果:
---》-->
MK5 静态变动态。简单动态。
以func2函数演示,获取系统时间,以实现动态效果。
socket端,重点在func2函数:
1 # Socket服务端 2 import socket 3 4 def index(request): 5 """ 6 处理用户请求,并返回响应数据 7 :param request: 用户请求的所有信息 8 :return: 9 """ 10 f = open("index.html","rb") 11 data = f.read() 12 f.close() 13 return data 14 15 def func2(request): 16 """ 17 处理用户请求,并返回响应数据 18 :param request: 用户请求的所有信息 19 :return: 20 """ 21 f = open("article.html","r") 22 data = f.read() 23 f.close() 24 import time 25 #导入时间模块 26 ctime = time.time() 27 #获取当期时间 28 data = data.replace("@@sw@@",str(ctime)) 29 #将当期时间与前端的标签位进行替换 30 return bytes(data,encoding="utf-8") 31 32 33 # 定义一个列表,里面存有url和url对应的函数名 34 Routers = [ 35 ("/index",index), #url 为XXX时,执行func1函数 36 ("/SSS",func2), #url 为SSS时,执行func2函数 37 ] 38 39 def run(): 40 """ 41 Socket服务端响应 42 :return: 43 """ 44 Socket = socket.socket() 45 # 创建Socket对象 46 Socket.bind(("127.0.0.1",8080)) 47 # 绑定IP和端口 48 Socket.listen(5) 49 # 监听的次数 50 while True: 51 #监听循环 52 conn, addr = Socket.accept() 53 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 54 data = conn.recv(8096) 55 # 获取数据 56 print(data) 57 #打印拿到的请求数据 58 data = str(data,encoding="utf-8") 59 #将data的数据类型,由byte类型转换成str类型。并编码为utf-8。 60 Headers,Bodys = data.split("\r\n\r\n") 61 #将data数据用split以"\r\n\r\n"分割成请求头和请求体 62 temp_list = Headers.split("\r\n") 63 #将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同 64 method,url,protocal = temp_list[0].split(" ") 65 #将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url 66 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 67 # 响应头 68 func_name = None 69 #定义一个func_name,用于赋值item的func函数 70 for item in Routers: 71 #循环遍历Routers列表里的url。 72 if item[0] == url: 73 #取出url进行判断 74 func_name = item[1] 75 #如果匹配到func指定的函数 76 break 77 if func_name: 78 #如果func_name=True,存在,就拿func_name 的值 79 response = func_name(data) 80 else: 81 response = b"404 Not Found" 82 conn.send(response) 83 #发送Response的值给作为响应体 84 conn.close() 85 86 87 if __name__ == "__main__": 88 run()
func2的页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>article</title> 6 </head> 7 <body> 8 <table border="2"> 9 <thead> 10 <tr> 11 <th>ID</th> 12 <th>Username</th> 13 <th>Email</th> 14 </tr> 15 </thead> 16 <tbody> 17 <tr> 18 <th>0001</th> 19 <th>@@sw@@</th> 20 <th>George@G.com</th> 21 </tr> 22 </tbody> 23 </table> 24 </body> 25 </html>
结果:
MK6,动态获取数据改为数据库获取。
重点在func3函数,要链接数据库。
socket端:
1 # Socket服务端 2 import socket 3 4 def index(request): 5 """ 6 处理用户请求,并返回响应数据 7 :param request: 用户请求的所有信息 8 :return: 9 """ 10 f = open("index.html","rb") 11 data = f.read() 12 f.close() 13 return data 14 15 def func2(request): 16 """ 17 处理用户请求,并返回响应数据 18 :param request: 用户请求的所有信息 19 :return: 20 """ 21 f = open("article.html","r") 22 data = f.read() 23 f.close() 24 import time 25 #导入时间模块 26 ctime = time.time() 27 #获取当期时间 28 data = data.replace("@@sw@@",str(ctime)) 29 #将当期时间与前端的标签位进行替换 30 return bytes(data,encoding="utf-8") 31 32 def func3(request): 33 """ 34 处理用户请求,并返回响应数据 35 :param request: 用户请求的所有信息 36 :return: 37 """ 38 import pymysql 39 conn = pymysql.connect(host = '127.0.0.1',port=3306,user="root",password="密码",db="数据库名") 40 #创建连接 41 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 42 #创建游标 43 effect_row = cursor.execute("select id,name,password from user") 44 #执行SQL语句,并返回结果 45 userlist = cursor.fetchall() 46 #拿到的所有数据 47 cursor.close() 48 #关闭游标 49 conn.close() 50 #关闭连接 51 print(userlist) 52 #打印user_list字典 53 """ 54 将user_list拼接成如下的字符串,将字典的每一个值对应发给每一个标签 55 [ 56 {id,name,password} 57 {id,...} 58 {id,...} 59 ] 60 61 <tr> 62 <td>%s</td> #id 63 <td>%s</td> #name 64 <td>%s</td> #password 65 </tr> 66 """ 67 content_list = [] 68 for row in userlist: 69 #每一个row都是一行数据 70 tp = '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' %(row['id'],row['name'],row['password']) 71 #字符串拼接 72 content_list.append(tp) 73 content = "".join(content_list) 74 f = open("user_list.html", "r",encoding='utf-8') 75 template = f.read() 76 f.close() 77 #模块的渲染, 78 data = template.replace('@@XXXXX@@',content) 79 return bytes(data, encoding="utf-8") 80 81 82 # 定义一个列表,里面存有url和url对应的函数名 83 Routers = [ 84 ("/index",index), #url 为XXX时,执行func1函数 85 ("/SSS",func2), #url 为SSS时,执行func2函数 86 ("/hhh",func3), #url 为hhh时,执行func3函数 87 ] 88 89 def run(): 90 """ 91 Socket服务端响应 92 :return: 93 """ 94 Socket = socket.socket() 95 # 创建Socket对象 96 Socket.bind(("127.0.0.1",8080)) 97 # 绑定IP和端口 98 Socket.listen(5) 99 # 监听的次数 100 while True: 101 #监听循环 102 conn, addr = Socket.accept() 103 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 104 data = conn.recv(8096) 105 # 获取数据 106 print(data) 107 #打印拿到的请求数据 108 data = str(data,encoding="utf-8") 109 #将data的数据类型,由byte类型转换成str类型。并编码为utf-8。 110 Headers,Bodys = data.split("\r\n\r\n") 111 #将data数据用split以"\r\n\r\n"分割成请求头和请求体 112 temp_list = Headers.split("\r\n") 113 #将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同 114 method,url,protocal = temp_list[0].split(" ") 115 #将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url 116 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 117 # 响应头 118 func_name = None 119 #定义一个func_name,用于赋值item的func函数 120 for item in Routers: 121 #循环遍历Routers列表里的url。 122 if item[0] == url: 123 #取出url进行判断 124 func_name = item[1] 125 #如果匹配到func指定的函数 126 break 127 if func_name: 128 #如果func_name=True,存在,就拿func_name 的值 129 response = func_name(data) 130 else: 131 response = b"404 Not Found" 132 conn.send(response) 133 #发送Response的值给作为响应体 134 conn.close() 135 136 137 if __name__ == "__main__": 138 run()
use_list.html 函数3的页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>user_list</title> 6 </head> 7 <body> 8 <table border="2"> 9 <thead> 10 <tr> 11 <th>ID</th> 12 <th>Username</th> 13 <th>Email</th> 14 </tr> 15 </thead> 16 <tbody> 17 @@XXXXX@@ 18 </tbody> 19 </table> 20 </body> 21 </html>
结果: 更改数据库name栏数据,图中username栏的数据会跟随变化。
MK7 优化函数func3中处理的繁琐字符串 :做模板渲染的 jinja2 模块。
重点func4函数:
func4函数的页面:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>func4</title> 6 </head> 7 <body> 8 <table border="1"> 9 <thead> 10 <tr> 11 <th>ID</th> 12 <th>用户名</th> 13 <th>邮箱</th> 14 </tr> 15 </thead> 16 <tbody> 17 {% for row in xxxxx %} 18 <tr> 19 <td>{{row.id}}</td> 20 <td>{{row.name}}</td> 21 <td>{{row.password}}</td> 22 </tr> 23 {% endfor %} 24 </tbody> 25 </table> 26 {{user}} 27 </body> 28 </html>
socket端:
1 # Socket服务端 2 import socket 3 4 def index(request): 5 """ 6 处理用户请求,并返回响应数据 7 :param request: 用户请求的所有信息 8 :return: 9 """ 10 f = open("index.html","rb") 11 data = f.read() 12 f.close() 13 return data 14 15 def func2(request): 16 """ 17 处理用户请求,并返回响应数据 18 :param request: 用户请求的所有信息 19 :return: 20 """ 21 f = open("article.html","r") 22 data = f.read() 23 f.close() 24 import time 25 #导入时间模块 26 ctime = time.time() 27 #获取当期时间 28 data = data.replace("@@sw@@",str(ctime)) 29 #将当期时间与前端的标签位进行替换 30 return bytes(data,encoding="utf-8") 31 32 def func3(request): 33 """ 34 处理用户请求,并返回响应数据 35 :param request: 用户请求的所有信息 36 :return: 37 """ 38 import pymysql 39 conn = pymysql.connect(host = '127.0.0.1',port=3306,user="root",password="密码",db="数据库名") 40 #创建连接 41 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 42 #创建游标 43 effect_row = cursor.execute("select id,name,password from user") 44 #执行SQL语句,并返回结果 45 userlist = cursor.fetchall() 46 #拿到的所有数据 47 cursor.close() 48 #关闭游标 49 conn.close() 50 #关闭连接 51 print(userlist) 52 #打印user_list字典 53 """ 54 将user_list拼接成如下的字符串,将字典的每一个值对应发给每一个标签 55 [ 56 {id,name,password} 57 {id,...} 58 {id,...} 59 ] 60 61 <tr> 62 <td>%s</td> #id 63 <td>%s</td> #name 64 <td>%s</td> #password 65 </tr> 66 """ 67 content_list = [] 68 for row in userlist: 69 #每一个row都是一行数据 70 tp = '<tr><td>%s</td><td>%s</td><td>%s</td></tr>' %(row['id'],row['name'],row['password']) 71 #字符串拼接 72 content_list.append(tp) 73 content = "".join(content_list) 74 f = open("user_list.html", "r",encoding='utf-8') 75 template = f.read() 76 f.close() 77 #模块的渲染, 78 data = template.replace('@@XXXXX@@',content) 79 return bytes(data, encoding="utf-8") 80 81 def func4(request): 82 """ 83 处理用户请求,并返回响应数据 84 :param request: 用户请求的所有信息 85 :return: 86 """ 87 import pymysql 88 conn = pymysql.connect(host='127.0.0.1', port=3306, user="root", password="redhat", db="GeorgeTest") 89 # 创建连接 90 cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) 91 # 创建游标 92 effect_row = cursor.execute("select id,name,password from user") 93 # 执行SQL语句,并返回结果 94 userlist = cursor.fetchall() 95 # 拿到的所有数据 96 cursor.close() 97 # 关闭游标 98 conn.close() 99 # 关闭连接 100 f = open('func4.html','r',encoding='utf-8') 101 data = f.read() 102 f.close() 103 104 # 基于第三方工具实现的模板渲染 105 from jinja2 import Template 106 template = Template(data) 107 data = template.render(xxxxx=userlist,name='fadfasdfa') 108 return data.encode('utf-8') 109 110 111 # 定义一个列表,里面存有url和url对应的函数名 112 Routers = [ 113 ("/index",index), #url 为XXX时,执行func1函数 114 ("/SSS",func2), #url 为SSS时,执行func2函数 115 ("/hhh",func3), #url 为hhh时,执行func3函数 116 ("/func4",func4), #url 为func4时,执行func4函数 117 ] 118 119 def run(): 120 """ 121 Socket服务端响应 122 :return: 123 """ 124 Socket = socket.socket() 125 # 创建Socket对象 126 Socket.bind(("127.0.0.1",8080)) 127 # 绑定IP和端口 128 Socket.listen(5) 129 # 监听的次数 130 while True: 131 #监听循环 132 conn, addr = Socket.accept() 133 # 在这hold住,等待用户发送的请求,有人来连接,获取用户的发送数据 134 data = conn.recv(8096) 135 # 获取数据 136 print(data) 137 #打印拿到的请求数据 138 data = str(data,encoding="utf-8") 139 #将data的数据类型,由byte类型转换成str类型。并编码为utf-8。 140 Headers,Bodys = data.split("\r\n\r\n") 141 #将data数据用split以"\r\n\r\n"分割成请求头和请求体 142 temp_list = Headers.split("\r\n") 143 #将请求头以“\r\n”分割,并且可以单独处理 [0] 的GET第一行,因为第一条的写法不同 144 method,url,protocal = temp_list[0].split(" ") 145 #将temp_list的 [0] 的内容分给请求方式,url和协议,以空格分开。url是请求的url 146 conn.send(b'HTTP/1.1 200 OK \r\n\r\n') 147 # 响应头 148 func_name = None 149 #定义一个func_name,用于赋值item的func函数 150 for item in Routers: 151 #循环遍历Routers列表里的url。 152 if item[0] == url: 153 #取出url进行判断 154 func_name = item[1] 155 #如果匹配到func指定的函数 156 break 157 if func_name: 158 #如果func_name=True,存在,就拿func_name 的值 159 response = func_name(data) 160 else: 161 response = b"404 Not Found" 162 conn.send(response) 163 #发送Response的值给作为响应体 164 conn.close() 165 166 167 if __name__ == "__main__": 168 run()
结果:
------ END ------