Web应用 http协议 Web框架
基于 socket 的 Web 应用
本质上:浏览器是一个socket客户端,服务器是一个socket服务端
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket def server_run(): soc = socket.socket() soc.bind(('127.0.0.1', 8008)) soc.listen(5) while True: conn, addr = soc.accept() recv_data = conn.recv(1024) print(recv_data) # 1 直接在send里写,发送给客户端 # conn.send(b'HTTP/1.1 200 OK\r\n\r\n<h1>hello web</h1><img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=5e3814acf9edab64607f4592965fc4a6/14ce36d3d539b600c0c465d0eb50352ac65cb74b.jpg"></img>') #2 打开一个html文件,发送给客户端 # with open('index.html','r',encoding='utf-8') as f: # data=f.read() # conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8')) # 3 动态网页,字符串替换 import time now=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) print(now) with open('index.html','r',encoding='utf-8') as f: data=f.read() data=data.replace('@@@',now) conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8')) conn.close() if __name__ == '__main__': server_run() <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>@@@</h2> <img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=5e3814acf9edab64607f4592965fc4a6/14ce36d3d539b600c0c465d0eb50352ac65cb74b.jpg" alt=""> </body> </html>
自己写的代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket soc = socket.socket( ) soc.bind(( '127.0.0.1',8001 )) soc.listen(5) while True: so ,addr = soc.accept() data = so.recv(1024) so.send(b'HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n') # so.send(b'sadf') print(data) data = str(data,encoding="utf-8") position = data.split('\r\n')[0].split(' ')[1] if '/index' == position: with open('index.html','rb') as f: da = f.read() so.send(da) else: so.send(b'404')
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>index</h1> <h2>dafdasdf</h2> <img src="https://gss0.bdstatic.com/-4o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=775f519ac08065386fe7ac41f6b4ca21/fd039245d688d43f63d84526771ed21b0ff43bf5.jpg"> </body> </html>
http协议特性
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传送协议。
-特点:1 基于TCP/IP协议之上的应用层协议
2 基于请求-响应模式(请求必定由客户端发送,服务端回复响应)
3 无状态保存(HTTP是一种不保存状态,级别,协议对于发送过的请求或响应都不做持久化处理。)
4 无连接(每次只处理一个请求,收到客户端应答后,即断开链接)
(4)无连接
无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
http请求协议与响应协议
http协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的请求协议。用于HTTP协议交互的信被为HTTP报文。请求端(客户端)的HTTP报文 做请求报文,响应端(服务器端)的 做响应报文。HTTP报文本身是由多行数据构成的字 文本。
请求协议
请求方式: get与post请求
-
GET提交的数据会放在URL之后,以?分割URL和传输数据,参数之间以&相连,如EditBook?name=test1&id=123456. POST方法是把提交的数据放在HTTP包的请求体中.
-
GET提交的数据大小有限制(因为浏览器对URL的长度有限制),而POST方法提交的数据没有限制.
-
GET与POST请求在服务端获取请求数据方式不同。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
GET请求 # 请求首行 GET / HTTP/1.1\r\n # get请求后面的参数 GET /?name=lqz&age=18 HTTP/1.1\r\n # 请求头 Host: 127.0.0.1:8008\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n Upgrade-Insecure-Requests: 1\r\n User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\n Accept-Language: zh-CN,zh;q=0.9\r\n Cookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n' # 请求体(get请求,请求体为空) POST请求 # 请求首行 POST /?name=lqz&age=18 HTTP/1.1\r\n # 请求头 Host: 127.0.0.1:8008\r\nConnection: keep-alive\r\nContent-Length: 21\r\nCache-Control: max-age=0\r\nOrigin: http://127.0.0.1:8008\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/65.0.3325.181 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:8008/?name=lqz&age=18\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n # 请求体 name=lqz&password=123'
响应协议
URL简介
统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。
格式:
协议://IP:端口(80)/路径?name=lqz&age=18
?之前的是请求路径,?之后的是请求数据部分
web框架
Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。浏览器和服务器的是基于HTTP协议进行通信的。也可以说web框架就是在以上十几行代码基础张扩展出来的,有很多简单方便使用的方法,大大提高了开发的效率。
wsgiref模块
我们不希望接触到TCP连接、HTTP原始请求和响应格式,所以,需要一个统一的接口协议来实现这样的服务器软件,让我们专心用Python编写Web业务。这个接口就是WSGI:Web Server Gateway Interface。而wsgiref模块就是python基于wsgi协议开发的服务模块
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def run(env, response): #收到请求协议,字典的形式 print(env) #响应格式 response("200 OK", [('Content-type', 'text/html')]) #查看路径 position = env['PATH_INFO'] func = None for url in urls: #判断路径是否跟函数名一致 if position == url[0]: func = url[1] break if func: response = func(env) else: response = error(env) return [response.encode('utf-8'),] if __name__ == '__main__': ser = make_server('127.0.0.1', 8003, run) ser.serve_forever()
Pymysql模块
前后台数据传输
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def user(env): conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', db='mydb', password='321') # 链接数据库 cur=conn.cursor(pymysql.cursors.DictCursor) # 获取游标,是查询记录变成字典的形式 cur.execute('select * from emp') # 输入sql语句 dic=cur.fetchall() # 查看记录 print(dic) # 渲染到前台 with open('templates/user.html', 'r') as f: data = f.read() tem = Template(data) response = tem.render(user_list=dic) return response def run(env,response): print(env) response("200 Ok",[("Content-type","text/html")]) position = env['PATH_INFO'] print(position) func = None for url in urls: if position == url[0]: func = url[1] break if func: response = func(env) else:response = error(env) return [response.encode('utf-8'),] if __name__ == "__main__": ser = make_server("127.0.0.1",8008,run) ser.serve_forever()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>pymsql</title> </head> <body> {% for user in user_list%} <td>{{user.name}}</td> //结束for循环 {% endfor %} <!--<table >--> <!--<tbody>--> <!--{% for user in user_list%}--> <!--<tr>--> <!--<td>{{user.name}}</td>--> <!--</tr>--> <!--{% endfor %}--> <!--</tbody>--> <!--</table>--> </body> </html>