1.HTTP协议|web框架
1、web应用
Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。应用程序有两种模式C/S、B/S。C/S是客户端/服务器端程序,也就是说这类程序一般独立运行。而B/S就是浏览器端/服务器端应用程序,这类应用程序一般借助谷歌,火狐等浏览器来运行。WEB应用程序一般是B/S模式。Web应用程序首先是“应用程序”,和用标准的程序语言,如java,python等编写出来的程序没有什么本质上的不同。在网络编程的意义下,浏览器是一个socket客户端,服务器是一个socket服务端。
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协议开发的服务模块。
from wsgiref.simple_server import make_ser
遵循http协议,字符串必须按照某种格式发给浏览器。
最简单的web请求过程:
服务端server
import socket
sock = socket.socket()
sock.bind(('127.0.0.1',))
sock.listen() while :
print('server waiting')
conn,addr = sock.accept() #请求
data = conn.recv() #拿到请求信息
print("data",data) <h1> Hello luffycity </h1>
conn.send(b"HTTP/1.1 200 OK\r\n\r\nHello luffycity!") #与浏览器的通讯,要遵循HTTP协议去发送请求数据,浏览器也会按这种协议进行解析;200是显示状态码,
conn.close() #前面为响应首行,后边是响应体,以\r\n两个空格隔开。 打印:
server waiting
data b'GET / 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/62.0.3202.75 Safari/537.36\r\nUpgrade-Insecure-Requests: 1\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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
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/62.0.3202.75 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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
import socket
sock = socket.socket()
sock.bind(('127.0.0.1',))
sock.listen() while :
print('server waiting')
conn,addr = sock.accept()
data = conn.recv()
print("data",data) #################读取html文件;直接返回一个html页面##################
with open('index.html','rb')as f:
data = f.read()
conn.send((b"HTTP/1.1 200 OK\r\n\r\n%s"%data))
conn.close() 打印:(get请求)
server waiting #第一个/ 为路径部分; GET / HTTP/1.1 为请求体;以换行符\r\n把他们隔开,都是一个个头-请求头;两个\r\n\r\n后边就是请求体
data 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; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
data b'GET /kris?name=kris&age=22 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/62.0.3202.75 Safari/537.36\r\nUpgrade-Insecure-Requests: 1\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\nCookie: sessionid=4sr81dc29tzw0gb1h2zxoqvumbbe6u1z; csrftoken=i1XjCb7mAKefMkNzUUqIvjHpL598C6IC8V0u0AKkPdh03eL7NzPvExLSBE1eLxOA\r\n\r\n'
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/62.0.3202.75 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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
####################Html文件代码################
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello Luffycity!</h1>
<img src="https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=16535fed6163f6241c5d3e05bf7f8cc5/fd039245d688d43f63d84526771ed21b0ff43bf5.jpg">
<a href="http://www.luffycity.com">路飞学城</a>
</body>
</html>
post请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:8800/" method="post">
用户名<input type="text" name="user">
密码<input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
import socket
sock = socket.socket()
sock.bind(('127.0.0.1',))
sock.listen() while :
print('server waiting')
conn,addr = sock.accept()
data = conn.recv() #
print("data",data) #读取html文件
with open('login.html','rb')as f:
data = f.read()
conn.send((b"HTTP/1.1 200 OK\r\n\r\n%s"%data))
conn.close() 打印:(post请求)
server waiting 请求首行,请求头、请求头、......,请求数据
data b'GET / 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/62.0.3202.75 Safari/537.36\r\nUpgrade-Insecure-Requests: 1\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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
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/62.0.3202.75 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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
data b''
server waiting
data b''
server waiting
data b''
server waiting
data b''
server waiting
data b'POST / HTTP/1.1\r\nHost: 127.0.0.1:8800\r\nConnection: keep-alive\r\nContent-Length: 20\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; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\nuser=egon&pwd=abc123'
server waiting
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/62.0.3202.75 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\nCookie: csrftoken=Mrqe5gm2pfaQy6LqXAJDqcWWU3BfTFrB0LMMhAEv2Pi0STKVn95bR6ODrDPZn34j\r\n\r\n'
server waiting
请求首行
请求头
请求头
请求头
.... 请求体(a=&b=) # 注意:只有POST请求才会有请求体 b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8880\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 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,en;q=0.8\r\nCookie: csrftoken=IU9cIEWdRzTx7gm6JIjASm9TZJSve8jUGcfXPbgTXpSW0iHot1NOxpjdroESRB4f\r\n\r\n'
b'GET /yuan?name=yuan&age=22 HTTP/1.1\r\nHost: 127.0.0.1:8880\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 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,en;q=0.8\r\nCookie: csrftoken=IU9cIEWdRzTx7gm6JIjASm9TZJSve8jUGcfXPbgTXpSW0iHot1NOxpjdroESRB4f\r\n\r\n'
b'POST / HTTP/1.1\r\nHost: 127.0.0.1:8880\r\nConnection: keep-alive\r\nContent-Length: 20\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nOrigin: http://127.0.0.1:8880\r\nUpgrade-Insecure-Requests: 1\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 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:8880/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\nCookie: csrftoken=IU9cIEWdRzTx7gm6JIjASm9TZJSve8jUGcfXPbgTXpSW0iHot1NOxpjdroESRB4f\r\n\r\nuser=bisheng&pwd=456' URL: 协议://IP:端口(80)/路径?a=1&b=2
?之前的都是路径,?之后的为请求数据
2、http协议简介
特性:
http协议是基于TCP/IP协议之上的应用层协议;
基于请求响应模式:先从客户端开始建立通信的,服务器端在没有 接收到请求之前不会发送响应;
无状态保持:HTTP是一种不保存状态,即无状态(stateless)协议,HTTP协议 自身不对请求和响应之间的通信状态进行保存,也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。
使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产 生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成 如此简单的。可是,随着Web的不断发展,因无状态而导致业务处理变得棘手 的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的 其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能 够掌握是谁送出的请求,需要保存用户的状态。HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能, 于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管 理状态了。
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
请求协议与响应协议
http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身是由多行数据构成的字 文本。
请求协议:请求报文的构成见下
get请求没有请求体,会放在url后面;只有post请求才有请求体;
请求方式: get与post请求
- GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的请求体中.
- GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
响应协议
响应格式:
响应状态码
重定向(地址搬家了,换成另外一个域名了。)
3.web框架
wsgi接口协议,基于接口实现的wsgiref
.ico是浏览器发的一个图标请求;
图标请求
wsgiref到底为我们做了什么事情?(解析数据和封装数据)
.拿到的那个字符串data就是根据Http协议封装好的,怎么解析它,拿到路径和数据信息呢??
按照http协议解包, dict/obj d={"path":"/login"}
#d.get("path") # 按着http请求协议解析数据 # 专注与web业务开发
# path=d.get("path") 取到当前请求的路径,
#
# if path=="/login":
# return login.html # 按着http响应协议封装数据 (组装Http响应格式,才能返回数据)
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协议开发的服务模块。
把data数据解析成environ字典;start_response和return共同组成一个相应体。
from wsgiref.simple_server import make_server def application(environ, start_response): #请求来了就用application来处理,回调函数;按着http协议解析数据所有的数据:把data数据解析成了environ这个字典;按这http协议进行组装数据,格式就是按照这种start_response来给我们处理格式
#按着http协议解析数据:environ;按着http协议组装数据:start_response
start_response('200 OK', [('Content-Type','text/html')]) #这里边放一个字符串(响应首行,'200 OK'),一个列表(响应头,可以为空);状态码、响应头
print("PATH", environ.get("PATH_INFO"))
path = environ.get("PATH_INFO") #获得当前请求路径
if path == "/favicon.ico":
'''return [b"hello favicon.ico"] #浏览器想得到一个图片你却给了它个字符串'''
with open("favicon.ico",'rb') as f:
data = f.read()
return [data]
return [b'<h1>Hello,web!</h1>'] #响应数据;响应首行、响应头、响应数据这3个(start_response和return)共同组成一个响应体;
httpd = make_server('', , application) #封装的socket;make_server要实例化下,传参实例化一个类对象; id地址、端口,调用application回调函数
print('Serving HTTP on port 8000.。')
#开始监听HTTP请求:
httpd.serve_forever() #等待用户链接:conn,addr=sock.accept();一旦请求进来它就回去调用application(environ,start_response)函数 打印:
Serving HTTP on port .。
PATH /kris
127.0.0.1 - - [/May/ ::] "GET /kris HTTP/1.1"
127.0.0.1 - - [/May/ ::] "GET /favicon.ico HTTP/1.1"
PATH /favicon.ico
方案一:
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 path == "/favicon.ico": #浏览器发的图标请求;
'''return [b"hello favicon.ico"] #浏览器想得到一个图片你却给了它个字符串''' hello favicon.ico,不应该返回一个字符串
with open("favicon.ico",'rb') as f: #把图标文件打开。
data = f.read()
return [data]
elif path == "/login":
with open("login.html","rb")as f:
data = f.read()
return [data] #wsgiref规定的返回的必须是字节数据;
elif path == "/index":
with open("index.html","rb")as f:
data = f.read()
return [data]
return [b'<h1>Hello,web!</h1>']
httpd = make_server('', , application) #封装的socket
print('Serving HTTP on port 8000.。')
#开始监听HTTP请求:
httpd.serve_forever()
#打印:
Serving HTTP on port .。
PATH /index
127.0.0.1 - - [/May/ ::] "GET /index HTTP/1.1"
127.0.0.1 - - [/May/ ::] "GET /index/login HTTP/1.1"
PATH /index/login
PATH /login
127.0.0.1 - - [/May/ ::] "GET /login HTTP/1.1"
方案2 改善
from wsgiref.simple_server import make_server def login(): #给它加个参数environ,下面传了你就要接收这个参数。给它传请求接收信息,它用不用的到再说;如想获取当前请求方式,请求数据都在environ这个字典里边。
with open("login.html","rb")as f:
data = f.read()
return data
def index(): #environ
with open("index.html","rb")as f:
data = f.read()
return data
def favi(): #environ
with open("favicon.ico", "rb")as f:
data = f.read()
return data #你们返回数据data,我把数据data返回到列表里即[func()] def reg(): #environ
with open("regs.html", "rb")as f:
data = f.read()
return data 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")
#解耦 #再多加个路径,给它加个元组就可以了。
url_patterns = [
("/login", login),
("/regs", reg),
("/index", index),
("/favicon.ico",favi)
] func = None
for item in url_patterns:
if path == item[]: #item[0] ---->> /login /regs /index /favicon.ico
func = item[] #跟上边的匹配成功了,执行这个函数就可以了。
break
if func: #func默认为None,都匹配不成功还是为None;func一旦有值,说明某次匹配成功了
return [func()] #返回个列表;函数执行了都有返回值,把函数的返回值data数据加到列表里边去; 给它加个参数environ即请求信息,必须给你传上,你函数用到就拿
else:
return [b'404!'] httpd = make_server('', , application) #封装的socket
print('Serving HTTP on port 8000.。')
#开始监听HTTP请求:
httpd.serve_forever() 打印:(与浏览器的交互)
Serving HTTP on port .。
PATH /
127.0.0.1 - - [/May/ ::] "GET / HTTP/1.1"
127.0.0.1 - - [/May/ ::] "GET /login HTTP/1.1"
PATH /login
PATH /reg
127.0.0.1 - - [/May/ ::] "GET /reg HTTP/1.1"
127.0.0.1 - - [/May/ ::] "GET /regs HTTP/1.1"
PATH /regs
继续优化(web框架的使用,若要加一个时间的功能函数,只需要加在url和视图函数里边添加就可以了)
把html和图标放在templates里边
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello Luffycity!</h1>
<img src="https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/w%3D268%3Bg%3D0/sign=16535fed6163f6241c5d3e05bf7f8cc5/fd039245d688d43f63d84526771ed21b0ff43bf5.jpg">
<a href="http://www.luffycity.com">路飞学城</a>
</body>
</html>
views.py(保存所有的视图函数和所有的逻辑处理函数的功能)
#把这些函数都放在一个py文件里边
def login(environ): #必须给它传请求接收信息,用不用得到再说
with open("templates/login.html","rb")as f:
data = f.read()
return data
def index(environ):
with open("templates/index.html","rb")as f:
data = f.read()
return data
def favi(environ):
with open("templates/favicon.ico", "rb")as f:
data = f.read()
return data #你们返回数据,我把数据返回到列表里 def reg(environ):
with open("templates/regs.html", "rb")as f:
data = f.read()
return data
urls.py(分发功能)
from views import *
url_patterns = [
("/login", login), #视图函数
("/regs", reg),
("/index", index),
("/favicon.ico",favi)
]
main.py(封装socket和整个程序的启动功能)
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") from urls import url_patterns
func = None
for item in url_patterns:
if path == item[]:
func = item[] #跟上边的login匹配成功了
break
if func:
return [func(environ)]
else:
return [b'404!'] httpd = make_server('', , application) #封装的socket
print('Serving HTTP on port 8000.。')
#开始监听HTTP请求:
httpd.serve_forever()
扩展框架关于数据库的操作
models.py
#生成用户表 import pymysql
#连接数据库
conn = pymysql.connect(host='127.0.0.1',port= 3306,user = 'root',passwd='',db='new_web') #db:库名
#创建游标
cur = conn.cursor() sql='''
create table userinfo(
id INT PRIMARY KEY ,
name VARCHAR(32) ,
password VARCHAR(32)
) '''
cur.execute(sql) #提交
conn.commit()
#关闭指针对象
cur.close()
#关闭连接对象
conn.close()
然后要去在mysql里边去创建用户表,添加字段。
mysql> create database new_web;
Query OK, 1 row affected (0.21 sec) mysql> use new_web;
Database changed
mysql>
mysql> show tables;
+-------------------+
| Tables_in_new_web |
+-------------------+
| userinfo |
+-------------------+
1 row in set (0.17 sec) mysql> desc userinfo;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(32) | YES | | NULL | |
| password | varchar(32) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
3 rows in set (0.04 sec) mysql> insert userinfo values(1,"kris","123");
Query OK, 1 row affected (0.24 sec) mysql> select * from userinfo;
+----+------+----------+
| id | name | password |
+----+------+----------+
| 1 | kris | 123 |
+----+------+----------+
1 row in set (0.00 sec)
urls.py
from views import *
url_patterns = [
("/login", login), #视图函数
("/regs", regs),
("/index", index),
("/favicon.ico",favi),
("/timer",timer),
("/auth",auth),
]
backend.html
<body>
<h3>login successful</h3>
</body>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h4>登录页面</h4>
<form action="http://127.0.0.1:8080/auth" method="post"> action=必须要加好,不然不跳转哦
用户名<input type="text" name="user">
密码<input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>
views.py
import pymysql
from urllib.parse import parse_qs
def timer(environ):
import datetime
now = datetime.datetime.now().strftime("%y-%m-%d %X")
return now.encode("utf8") def auth(request): #把用户名和密码取出来
try:
request_body_size = int(request.get('CONTENT_LENGTH', 0)) #拿到请求体的长度
except (ValueError):
request_body_size = 0
request_body = request['wsgi.input'].read(request_body_size)
data = parse_qs(request_body) user = data.get(b"user")[0].decode("utf8")
pwd = data.get(b"pwd")[0].decode("utf8") # 连接数据库
conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='new_web') # db:库名
# 创建游标
cur = conn.cursor()
SQL = "select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'" % (user, pwd)
cur.execute(SQL) if cur.fetchone():
f = open("templates/backend.html", "rb")
data = f.read()
data = data.decode("utf8")
return data.encode("utf8")
else:
return b"user or pwd is wrong"
web框架 功能总结
1.HTTP协议|web框架的更多相关文章
- web应用/http协议/web框架
一.web应用 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件.应用程序有两种模式C/S.B/S.C/S是客户端 ...
- Django web 应用 http 协议 web框架
一:什么是web 应用程序 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件 应用程序有两种模式C/S.B/S. ...
- 1 web应用-http协议-web框架
web 应用 Web 应用程序是一种可以通过 Web 访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件.应用程序有两种模式 C/S.B/S.C/S ...
- Python-web应用 +HTTP协议 +web框架
web架构 # web应用 架构# C/S 架构 | B/S 架构# client server: 客户端服务器架构,C++# browser server:浏览器服务器架构,Java.Python ...
- 自创Web框架之过度Django框架
目录 自创Web框架之过度Django框架 软件开发架构 HTTP协议 Web框架之"撸起袖子加油干" Web框架之通过wsgiref加油干 封装优化处理 动静网页 jinjia2 ...
- Web 应用 WEB框架 HTTP协议 初识Django
----------------------------财富存在于人的思想里,你没找到路,不等于没有路,你想知道将来要得到什么,你必须知道现在应该先做什么和先放弃什么! [web 应用] web应用 ...
- python 全栈开发,Day66(web应用,http协议简介,web框架)
一.web应用 web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件.应用程序有两种模式C/S.B/S.C/S是客户端 ...
- HTTP协议与WEB框架简介
HTTP协议与WEB框架简介 一.HTTP协议 HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wid ...
- (1)什么是web框架和http协议
Django是一个web框架 web框架的本质:就是一个socket服务端 bs架构本质上就是cs架构(cs架构就是client和server):bs架构就是browser和server,本质上bro ...
随机推荐
- Javaweb中提到的反射浅析(附源码)
反射:一个jdk5.0的新特性,高级运用.在后期的框架中,这个是一大重点,现在估计我们都不会太多的接触他的.但是为了后面的铺垫,我想还是先了解一下: 先构造一个类,然后我们用反射来获取,调用里面的方法 ...
- dp填表法,刷表法
填表法:利用上一状态推当前 刷表法:利用当前推关联,利用刷表法较为便捷,向上边界较容易处理,处理在本次循环中的影响
- OpenCV在字符提取中进行的预处理(转)
OCR简介熟悉OCR的人都了解,OCR大致分为两个部分: -文字提取text extractor -文字识别text recognition 其中,第一部分是属于图像处理部分,涉及到图像分割的知识,而 ...
- sql 行变列
select * from market//查看原来所有数据 //第一种方式 select max(case area when '南京' then num else 0 end) 南京, max(c ...
- [C++]Linux之Ubuntu下编译C程序出现错误:“ stray ‘\302'或者'\240' in program”的解决方案
参考文献:[error: stray ‘\240’ in program或 error: stray ‘\302’ in program](http://blog.csdn.net/u01299585 ...
- luogu P3674 小清新人渣的本愿
传送门 毒瘤lxl 本质是莫队,关键是怎么处理询问 这里需要开两个bitset(记为\(b1,b2\)),分别存\(x\)和\(n-x\)是否出现 对于询问1,即\(x-y=z\),由于\(y=x-z ...
- 2018-2019-2 网络对抗技术 20165320 Exp2 后门原理与实践
后门原理与实践 windows获取Linux操作Shell 获取本机的IP netcat介绍:一个进行基本的TCP.UDP数据收发的工具 相关的参数与具体用法 windows打开监听: ncat.ex ...
- Python爬虫-爬取百度贴吧帖子
这次主要学习了替换各种标签,规范格式的方法.依然参考博主崔庆才的博客. 1.获取url 某一帖子:https://tieba.baidu.com/p/3138733512?see_lz=1&p ...
- 腾讯云启动数据库进程,提示No such host is known
回想一下,系统是否切换过外网IP,切换过则检查/etc/hosts文件中IP和主机名对应关系 现象:出错前一直做域名解析
- linux内核驱动中对字符串的操作【转】
转自:http://www.360doc.com/content/12/1224/10/3478092_255969530.shtml Linux内核中关于字符串的相关操作,首先包含头文件: #inc ...