web应用/http协议/web框架
一、web应用
Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。
应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序一般独立运行。而B/S就是浏览器端/服务器端应用程序,
这类应用程序一般借助谷歌,火狐等浏览器来运行。WEB应用程序一般是B/S模式。Web应用程序首先是“应用程序”,和用标准的程序语言,
如java,python等编写出来的程序没有什么本质上的不同。在网络编程的意义下,浏览器是一个socket客户端,服务器是一个socket服务端
1.一个简单的web请求过程:
1 # -*- coding:utf-8 -*- 2 3 4 import socket 5 6 sock = socket.socket() 7 sock.bind(('127.0.0.1',8800)) 8 sock.listen(5) 9 10 # get请求 11 12 while True: 13 print('server waiting......') 14 conn,addr = sock.accept() 15 data = conn.recv(1024) 16 print("data:",data) 17 # conn.send(b"hello mm.") # 格式错误,浏览器显示(127.0.0.1 发送的响应无效。) 18 conn.send(b"HTTP/1.1 200 OK\r\n\r\n<h1>hello mm.</h1>") 19 conn.close() 20 21 # HTTP/1.1:版本 22 # 200:响应状态码,表示没有问题 OK:文本解释,和200并行的 23 # \r\n\r\n:响应首行和响应体的固定分格格式 24 25 # 打印 26 server waiting...... 27 data: b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n' 28 server waiting...... 29 data: b'GET /favicon.ico HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36\r\nAccept: image/webp,image/apng,image/*,*/*;q=0.8\r\nReferer: http://127.0.0.1:8800/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n' 30 server waiting......
浏览器显示:
问题:由于一个页面不是简单的这几个标签,所以不应该这么写(<h1>hello mm.</h1>),应该单独写一个html,然后读进来
index.html文件:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h1>Hello Kobe.</h1> 9 <img src="https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=27a6723e4c2309f7e76faa144a356bce/9e3df8dcd100baa1a5fd20114d10b912c9fc2e42.jpg" alt=""> 10 <a href="https://baike.baidu.com/item/%E7%A7%91%E6%AF%94%C2%B7%E5%B8%83%E8%8E%B1%E6%81%A9%E7%89%B9/318773?fromtitle=%E7%A7%91%E6%AF%94&fromid=133066&fr=aladdin">click</a> 11 </body> 12 </html>
修改后的服务器程序:
get请求:
1 import socket 2 3 sock = socket.socket() 4 sock.bind(('127.0.0.1',8800)) 5 sock.listen(5) 6 7 # get请求 8 9 while True: 10 print('server waiting......') 11 conn,addr = sock.accept() 12 data = conn.recv(1024) 13 print("data:",data) 14 # 读取html文件 15 with open("index.html","r") as f: 16 d = f.read() 17 18 conn.send(("HTTP/1.1 200 OK\r\n\r\n%s"%d).encode("utf-8"))# 字符串转换为字节传送 19 conn.close()
浏览器显示:
2、http协议简介
1.简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传送协议。
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。
HTTP协议工作于客户端-服务端架构为上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。Web服务器根据接收到的请求后,向客户端发送响应信息。
2.特性
(1) 基于TCP/IP
http协议是基于TCP/IP协议之上的应用层协议。
(2) 基于请求-响应模式
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应。
(3) 无状态保存
HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议 自身不对请求和响应之间的通信状态进行保存。
也就是说在HTTP这个 级别,协议对于发送过的请求或响应都不做持久化处理。
使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。
这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。
可是,随着Web的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,
也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。
HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能, 于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管理状态了。
有关Cookie的详细内容之后讲解。
(4)无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
3.http请求协议与响应协议
http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的响应协议。
用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。
HTTP报文本身是由多行数据构成的文本。
![](https://img2018.cnblogs.com/blog/1228710/201901/1228710-20190109173256446-458277471.png)
请求协议
请求格式:
请求方式: get与post请求
GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456。POST方法是把提交的数据放在HTTP包的请求体中.
GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
GET与POST请求在服务端获取请求数据方式不同。
响应协议
响应格式:
响应状态码
状态码的是当客户端向服务器端发送请求时, 返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了问题 。
状态码如200 OK,以3位数字和原因组成。数字中的 一位指定了响应类别,后两位无分。响应分为别5种。
post请求:
1 # -*- coding:utf-8 -*- 2 3 4 import socket 5 6 sock = socket.socket() 7 sock.bind(('127.0.0.1',8800)) 8 sock.listen(5) 9 10 while True: 11 print('server waiting......') 12 conn,addr = sock.accept() 13 data = conn.recv(1024) 14 print("data:",data) 15 with open("login.html","r",encoding="utf-8") as f: 16 d = f.read() 17 conn.send(("HTTP/1.1 200 OK\r\n\r\n%s"%d).encode("utf-8")) # 字符串转换为字节传送 18 conn.close() 19 20 ''' 21 http请求协议: 22 23 第一个\r\n是请求首行,接下来的\r\n都是请求头,直到遇到\r\n\r\n,最后的是请求体(注意:只有POST请求才有请求体) 24 25 get请求:查询操作时使用 26 b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n' 27 28 post请求:数据库更改操作时使用 29 b'POST / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nContent-Length: 15\r\nCache-Control: max-age=0\r\nOrigin: http://127.0.0.1:8800\r\nUpgrade-Insecure-Requests: 1\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nReferer: http://127.0.0.1:8800/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\nuser=mm&pwd=123' 30 31 32 GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. 33 POST方法是把提交的数据放在HTTP包的Body中. 34 '''
login.html:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <form action="http://127.0.0.1:8800/" method="post"> 9 用户名 <input type="text" name="user"> 10 密码 <input type="password" name="pwd"> 11 <input type="submit"> 12 </form> 13 14 </body> 15 </html>
三、web框架
Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式,
也为web行为提供了一套通用的方法。web框架已经实现了很多功能,开发人员使用框架提供的方法并且完成自己的业务逻辑,就能快速开发web应用了。
浏览器和服务器的是基于HTTP协议进行通信的。也可以说web框架就是在十几行代码基础上扩展出来的,有很多简单方便使用的方法,大大提高了开发的效率。
wsgiref模块
最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回
如果要动态生成HTML,就需要把上述步骤自己来实现。不过,接受HTTP请求、解析HTTP请求、发送HTTP响应都是苦力活,
如果我们自己来写这些底层代码,还没开始写动态HTML呢,就得花个把月去读HTTP规范。
正确的做法是底层代码由专门的服务器软件实现,我们用Python专注于生成HTML文档。
因为我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,
让我们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块。
1 # -*- coding:utf-8 -*- 2 3 ''' 4 按着http请求协议解析数据 5 6 专注于web业务开发 7 8 按着http响应协议封装数据 9 ''' 10 11 from wsgiref.simple_server import make_server 12 13 def application(environ,start_response): 14 # 按着http协议解析数据:environ 15 # 按着http协议封装数据:start_response 16 17 print(environ) 18 print(type(environ)) 19 20 # 当前请求路径 21 path = environ.get("PATH_INFO") 22 start_response('200 OK',[('Content-Type','text/html')]) 23 global data 24 if path == "/login": 25 with open("login.html","r",encoding="utf-8") as f: 26 data = f.read() 27 # return [data.encode("utf-8")] 28 elif path == "/index": 29 with open("index.html","r",encoding="utf-8") as f: 30 data = f.read() 31 # return [data.encode("utf-8")] 32 33 return [data.encode("utf-8")] 34 # return [b"<h1>Hello Mumu</h1>"] 35 36 # 封装socket 37 httped = make_server("",8800,application) # 回调函数application 38 39 # 等待用户链接:conn,addr = sock.accept() 40 httped.serve_forever() # application(environ,start_response) 接收两个参数 41 42 43 ''' 44 'CONTENT_LENGTH': '', 45 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', 46 'PYTHONUNBUFFERED': '1', 47 'HTTP_CACHE_CONTROL': 'max-age=0', 48 'SYSTEMROOT': 'C:\\Windows', 49 'PROCESSOR_REVISION': '3a09', 50 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY', 51 'SERVER_PROTOCOL': 'HTTP/1.1', 52 'HOMEDRIVE': 'C:', 53 'WINDIR': 'C:\\Windows', 54 'COMPUTERNAME': 'PC-PC', 55 'PATH': 'C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x86;C:\\Program Files (x86)\\Intel\\OpenCL SDK\\2.0\\bin\\x64;export PATH=C:\\ProgramData\\Anaconda3/anaconda/bin:$PATH;C:\\Python34;C:\\Python34\\Scripts;C:\\Users\\Administrator\\Anaconda3;C:\\Users\\Administrator\\Anaconda3\\Scripts;F:\\mysql56\\bin;', 56 'PYTHONPATH': 'F:\\Python全栈开发_中级', 57 'wsgi.run_once': False, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='GBK'>, 58 'REQUEST_METHOD': 'GET', 59 'COMMONPROGRAMFILES': 'C:\\Program Files (x86)\\Common Files', 60 'PSMODULEPATH': 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\', 61 'PROCESSOR_ARCHITECTURE': 'x86', 62 'PUBLIC': 'C:\\Users\\Public', 63 'REMOTE_ADDR': '127.0.0.1', 64 'FP_NO_HOST_CHECK': 'NO', 65 'PROGRAMDATA': 'C:\\ProgramData', 66 'ALLUSERSPROFILE': 'C:\\ProgramData', 67 'CONTENT_TYPE': 'text/plain', 68 'PYTHONIOENCODING': 'GBK', 69 'PROGRAMFILES': 'C:\\Program Files (x86)', 70 'HTTP_HOST': '127.0.0.1:8800', 71 'QUERY_STRING': '', 72 'TEMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 73 'APPDATA': 'C:\\Users\\Administrator\\AppData\\Roaming', 74 'HTTP_CONNECTION': 'keep-alive', 75 'SERVER_NAME': 'pc-PC', 76 'SERVER_PORT': '8800', 77 'NUMBER_OF_PROCESSORS': '4', 78 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 79 'PATH_INFO': '/', 80 'PROCESSOR_LEVEL': '6', 81 'wsgi.multiprocess': False, 82 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 83 'TMP': 'C:\\Users\\ADMINI~1\\AppData\\Local\\Temp', 'LOGONSERVER': '\\\\PC-PC', 'PYCHARM_HOSTED': '1', 'PROCESSOR_ARCHITEW6432': 'AMD64', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'wsgi.multithread': True, 'REMOTE_HOST': '', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8', 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>, 'OS': 'Windows_NT', 'SYSTEMDRIVE': 'C:', 'USERDOMAIN': 'pc-PC', 'SCRIPT_NAME': '', 'wsgi.input': <_io.BufferedReader name=612>, 'wsgi.version': (1, 0), 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'HOMEPATH': '\\Users\\Administrator', 'USERNAME': 'Administrator', 'LOCALAPPDATA': 'C:\\Users\\Administrator\\AppData\\Local', 'USERPROFILE': 'C:\\Users\\Administrator', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'wsgi.url_scheme': 'http', 'GATEWAY_INTERFACE': 'CGI/1.1', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 58 Stepping 9, GenuineIntel', 'SESSIONNAME': 'Console', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'PROGRAMW6432': 'C:\\Program Files'} 84 85 '''
DIY一个web框架:
方案一:
# -*- coding:utf-8 -*- from wsgiref.simple_server import make_server def application(environ,start_response): #请求来了就用application来处理;所有的数据都在environ这个字典里,start_response来给我们处理格式 start_response('200 OK',[('Content-Type','text/html')]) #状态码、响应头 print("PATH",environ.get("PATH_INFO")) path = environ.get("PATH_INFO") # 方案一:if else太多,太low if path == "/favicon.ico": #浏览器发的图标请求; # return [b"hello favicon.ico"] #浏览器想得到一个图片你却给了它个字符串hello favicon.ico, 不应该返回一个字符串 with open("favicon.ico","rb") as f: #把图标文件打开。 data = f.read() return [data] #wsgiref规定的返回的必须是字节数据; elif path == "/login": with open("login.html", "rb") as f: data = f.read() return [data] elif path == "/index": with open("index.html", "rb") as f: data = f.read() return [data] # 封装socket httped = make_server('',8800,application) print('Serving HTTP on port 8800...') # 开始监听HTTP请求: httped.serve_forever() # 打印 Serving HTTP on port 8800... PATH /index 127.0.0.1 - - [09/Jan/2019 19:18:59] "GET /index HTTP/1.1" 200 166 PATH /favicon.ico 127.0.0.1 - - [09/Jan/2019 19:18:59] "GET /favicon.ico HTTP/1.1" 200 4 PATH /login 127.0.0.1 - - [09/Jan/2019 19:19:03] "GET /login HTTP/1.1" 200 341 127.0.0.1 - - [09/Jan/2019 19:19:03] "GET /favicon.ico HTTP/1.1" 200 4 PATH /favicon.ico
方案二 改善
1 # -*- coding:utf-8 -*- 2 3 from wsgiref.simple_server import make_server 4 5 def login(environ): 6 with open("login.html", "rb") as f: 7 data = f.read() 8 return data 9 10 def index(environ): 11 with open("index.html", "rb") as f: 12 data = f.read() 13 return data 14 15 def fav(environ): 16 with open("favicon.ico", "rb") as f: 17 data = f.read() 18 return data 19 20 def application(environ,start_response): 21 #请求来了就用application来处理;所有的数据都在environ这个字典里,start_response来给我们处理格式 22 23 start_response('200 OK',[('Content-Type','text/html')]) #状态码、响应头 24 25 print("PATH",environ.get("PATH_INFO")) 26 27 path = environ.get("PATH_INFO") 28 29 # 解耦 #再多加个路径,给它加个元组就可以了。 30 url_parrents = [ 31 ("/login",login), 32 ("/index",index), 33 ("/favicon",fav), 34 ] 35 36 func = None 37 for item in url_parrents: 38 if item[0] == path: #item[0] ---->> /login/index/favicon.ico 39 func = item[1] #跟上边的匹配成功了,执行这个函数就可以了 40 break 41 42 if func: #func默认为None,都匹配不成功还是为None;func一旦有值,说明某次匹配成功了 43 return [func(environ)] # 特别注意,返回的时候数据需要用[] 44 else: 45 return [b'404!'] 46 47 # return [b'<h1>Hello mumu</h1>'] 48 49 # 封装socket 50 httped = make_server('',8800,application) 51 52 print('Serving HTTP on port 8800...') 53 # 开始监听HTTP请求: 54 httped.serve_forever() 55 56 # 打印 57 Serving HTTP on port 8800... 58 PATH /index 59 127.0.0.1 - - [09/Jan/2019 19:21:45] "GET /index HTTP/1.1" 200 166 60 127.0.0.1 - - [09/Jan/2019 19:21:46] "GET /favicon.ico HTTP/1.1" 200 4 61 PATH /favicon.ico 62 127.0.0.1 - - [09/Jan/2019 19:21:51] "GET /login HTTP/1.1" 200 341 63 PATH /login 64 PATH /favicon.ico 65 127.0.0.1 - - [09/Jan/2019 19:21:51] "GET /favicon.ico HTTP/1.1" 200 4
方案三 优化
models.py
1 # -*- coding:utf-8 -*- 2 3 # 生成用户表 4 5 import pymysql 6 7 # 连接数据库 8 conn = pymysql.connect(host='127.0.0.1',port=3306,user = 'root',password='123',db='new_web') 9 10 # 创建游标 11 cur = conn.cursor() 12 13 sql = ''' 14 create table userinfo( 15 id INT PRIMARY KEY , 16 name VARCHAR(32) , 17 password VARCHAR(32) 18 ) 19 ''' 20 21 cur.execute(sql) 22 23 # 提交 24 conn.commit() 25 # 关闭指针对象 26 cur.close() 27 # 关闭链接对象 28 conn.close()
启动文件 manage.py
1 # -*- coding:utf-8 -*- 2 3 from wsgiref.simple_server import make_server 4 from urls import url_parrents 5 from urllib.parse import parse_qs 6 7 def application(environ,start_response): 8 start_response('200 OK',[('Content-Type','text/html')]) 9 10 print("PATH",environ.get("PATH_INFO")) 11 12 path = environ.get("PATH_INFO") 13 14 func = None 15 for item in url_parrents: 16 if item[0] == path: 17 func = item[1] 18 break 19 20 if func: 21 return [func(environ)] # 特别注意,返回的时候数据需要用[] 22 else: 23 return [b'404!'] 24 25 # return [b'<h1>Hello mumu</h1>'] 26 27 # 封装socket 28 httped = make_server('',8800,application) 29 30 print('Serving HTTP on port 8800...') 31 # 开始监听HTTP请求: 32 httped.serve_forever()
urls.py
1 # -*- coding:utf-8 -*- 2 3 from views import * 4 url_parrents = [ 5 ("/login",login), 6 ("/index",index), 7 ("/favicon",fav), 8 ("/timer",timer), 9 ("/auth",auth), 10 ]
views.py
1 # -*- coding:utf-8 -*- 2 from urllib.parse import parse_qs 3 4 def login(environ): 5 with open("Templates/login.html", "rb") as f: 6 data = f.read() 7 return data 8 9 10 def index(environ): 11 with open("Templates/index.html", "rb") as f: 12 data = f.read() 13 return data 14 15 16 def fav(environ): 17 with open("Templates/favicon.ico", "rb") as f: 18 data = f.read() 19 return data 20 21 def timer(environ): 22 import datetime 23 24 now = datetime.datetime.now().strftime("%y-%m-%d %X") 25 return now.encode('utf-8') 26 27 def auth(request): 28 try: 29 request_body_size = int(request.get('CONTENT_LENGTH',0)) 30 except (ValueError): 31 request_body_size = 0 32 33 request_body = request['wsgi.input'].read(request_body_size) 34 data = parse_qs(request_body) 35 36 user = data.get(b"user")[0].decode("utf-8") 37 pwd = data.get(b"pwd")[0].decode("utf-8") 38 39 # 连接数据库 40 import pymysql 41 conn= conn = pymysql.connect(host='127.0.0.1',port=3306,user = 'root',password='123',db='new_web') 42 43 # 创建游标 44 cur = conn.cursor() 45 sql = "select * from userinfo WHERE NAME ='%s' AND PASSWORD = '%s'" % (user,pwd) 46 cur.execute(sql) 47 48 if cur.fetchone(): 49 f = open("templates/backend.html","rb") 50 data = f.read() 51 data = data.decode("utf-8") 52 return data.encode("utf-8") 53 # return data 54 else: 55 print("OK456") 56 return b"user or pwd is wrong"
login.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h4>登录页面</h4> 9 <form action="http://127.0.0.1:8800/auth" method="post"> 10 用户名 <input type="text" name="user"> 11 密码 <input type="password" name="pwd"> 12 <input type="submit"> 13 </form> 14 15 </body> 16 </html>
index.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 9 <h4>welcome mumu home</h4> 10 11 </body> 12 </html>
backend.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 </head> 7 <body> 8 <h3>index</h3> 9 </body> 10 </html>
web框架 功能总结:
manage.py:启动文件,封装了socket
1.urls.py:路径与视图函数映射关系 --- url控制器
2.views.py:视图函数,固定有一个形式参数:environ --- 视图函数
3.templates文件夹:html文件 --- 模板
4.models:在项目启动前,在数据库中创建表结构 --- 与数据库相关