HTTP协议
超文本传输协议
四大特性:
1.基于TCP/IP作用在应用层上的协议
2.基于请求响应
3.无连接
4.无状态
数据格式之请求
请求首行
请求头(一堆k,v键值对)
/r/n
请求体
数据格式值响应
响应首行
响应头(一堆k,v键值对)
/r/n
响应体
响应状态码
10x 服务端已经接受你的数据 正在处理 你可以继续提交数据
20x 请求成功
30x 重定向
40x 请求错误(404:请求资源不存在)
50x 服务器内部错误
动静态网页
静态页面:
数据是写死的 万年不变
动态页面:
数据是实时获取的 比如后端获取当前时间展示到前端,从数据库获取数据展示到前端等
推导版本(django)
首先创建web框架
import socket
"""
请求头
b'GET / HTTP/1.1\r\n'
请求首行(一大堆的k,v键值对组成)
b'Host: 127.0.0.1:8080\r\n'
b'Connection: keep-alive\r\n'
b'Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n'
请求体
"""
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
conn, addr = server.accept()
data = conn.recv(1024)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
print(data)
data = data.decode('utf-8')
current_path = data.split('\r\n')[0].split(' ')[1]
if current_path == '/index':
# conn.send(b'<h1>hello baby!</h1>')
with open('01 纯手撸版本对应的html页面.html','rb') as f:
conn.send(f.read())
else:
conn.send(b'404')
conn.close()
然后基于wsgiref实现服务端
from wsgiref.simple_server import make_server
from urls import urls
from views import *
def run(env,response):
print(env) # 是个字典类型
# 固定写法
response('200 OK',[]) # 列表里面放的是请求首行的信息,可以不放,但是必须写
# 获取当前用户访问路径
current_path = env.get('PATH_INFO')
# 定义一个函数标志位
func = None
for url_list in urls: # urls:[[],[],[]] url_list:['',func]
if current_path == url_list[0]:
func = url_list[1]
# 结束for循环了
break
if func:
res = func(env)
else:
# 匹配不上 走error
res = error(env)
return [res.encode('utf-8')]
if __name__ == '__main__':
server = make_server('127.0.0.1',8888,run)
server.serve_forever()
然后路由实现映射视图
from views import *
urls = [
['/index',index],
['/login',login],
['/reg',reg],
['/get_time',get_time],
['/xxx',get_user],
['/get_db',get_db_info]
]
视图渲染页面
from datetime import datetime
from jinja2 import Template
import pymysql
def index(env):
with open('templates/index.html','r',encoding='utf-8') as f:
data = f.read()
return data
def login(env):
return 'login'
def error(env):
return '404 error'
def reg(env):
return 'reg'
def get_time(env):
ctime = datetime.now().strftime('%Y-%m-%d %X')
# 打开文件
with open('templates/get_time.html','r',encoding='utf-8') as f:
data = f.read()
res = data.replace('@@time@@',ctime)
return res
def get_user(env):
user = {'name':'jason','age':'18'}
with open('templates/get_user.html','r',encoding='utf-8') as f:
data = f.read()
tmp = Template(data)
res = tmp.render(data=user)
return res
def get_db_info(env):
conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '123321',
database = 'test007',
charset = 'utf8',
autocommit = True
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from userinfo')
user_list = cursor.fetchall()
# 打开文件渲染到前端页面
with open('templates/get_db_user.html','r',encoding='utf-8') as f:
data = f.read()
tmp = Template(data)
res = tmp.render(user_list=user_list)
return res
其中html文件可放在 templates文件夹中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script class="lazy" data-src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script class="lazy" data-src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<table class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
</tr>
</thead>
<tbody>
{% for data in user_list %}
<tr>
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.age}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script class="lazy" data-src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstrap-3.3.7/css/bootstrap.min.css">
<script class="lazy" data-src="bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
@@time@@
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script class="lazy" data-src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstrap-3.3.7/css/bootstrap.min.css">
<script class="lazy" data-src="bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h1>{{ data }}</h1>
<h1>{{ data.name }}</h1>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('name') }}</h1>
<h1>{{ data.age }}</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script class="lazy" data-src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bootstrap-3.3.7/css/bootstrap.min.css">
<script class="lazy" data-src="bootstrap-3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<h1>index</h1>
</body>
</html>
模板语法(接近python语法)
<h1>{{ data }}</h1>
<h1>{{ data.name }}</h1>
<h1>{{ data['name'] }}</h1>
<h1>{{ data.get('name') }}</h1>
<h1>{{ data.age }}</h1>
jinja循环:
{% for data in user_list %}
<tr>
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.age}}</td>
</tr>
{% endfor %}
模板渲染(雏形):
后端获取数据,传递给前端页面,页面上可以通过某些方法,使用到后端传递过来的数据
推导思路
1.纯手写
2.借助wsgiref帮我实现socket这块
3.先拆分成不同文件 模块渲染由自己的字符串替换变成第三方模块(jinja2)
推导流程图:
python三大主流web框架介绍
django(大而全)
flask(小而精)
tornado(异步非阻塞)
a:socket
b:路由与视图函数
c:模板渲染
django:a:用的别人的wsgiref b:自己写的 c:自己写的
flask:a:用的别人的werkzeug b:自己写的 c:用的别人的jinja2
tornado:都是自己写的
django简介
注意:
1.django版本
2.计算机名不能是中文
3.一个pycharm窗口就一个工程
安装
命令行下载
pip3 install django==1.11.11
命令行创建django项目
django-admin startproject mysite
命令行创建app
python manage.py startapp 应用名
命令行启动django
python manage.py runserver
用命令行创建的时候,默认没有templates文件夹,需要你自己手动创建
并且在settings配置文件中写上路径
pycharm下载
点加号 选版本
创建new project选第二个django项目(选本机环境 暂时不要选虚拟环境)
两种创建app的方式:
python manage.py startapp应用名
tools下面的run manage.py 能够简写并自动提示
运行方式
python manage.py runserver
pycharm自动启动
创建的app需要在settings里进行添加:
还可以修改端口号:
django主要文件介绍
app01
migrations 数据库迁移记录相关
models.py orm模型类
views.py 视图函数
templates 放html文件
manage.py django的启动入口文件
项目名下
setttings.py django项目的配置文件
urls.py 路由与视图函数的映射关系
django小白必会三板斧
HttpResponse 返回字符串
render 渲染页面并返回
redirect 重定向
django默认能够自动重启,但是速度可能没有那么快