一,web框架的原理
1、浏览器(socket客户端),网站的服务器(socket服务端)
2、HTTP协议
1.目前被广泛使用的版本为HTTP/1.1(1999),最新的版本是HTTP/2(2015)
2.http默认端口为80,https默认端口为443
3.请求(request)的消息格式 -->浏览器给服务器发送消息
1.请求行:请求方法+\s+url+\s+协议版本
2.请求头:头部字段名:值
3.空行
4.请求体,请求数据(可有可无)
GET / HTTP/1.1 #请求行:请求方法+url(此处为根目录)+协议版本Host: www.baidu.com #请求头 开始Connection: keep-alivePragma: no-cacheCache-Control: no-cacheUpgrade-Insecure-Requests: 1User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflate, brAccept-Language: zh-CN,zh;q=0.9,en;q=0.8Cookie: BAIDUID=846909BF8367CC3D9F47D47316FCA30B:FG=1; #请求头 结束 #空行 #请求体,请求数据(可有可无)
4.响应(response)的消息格式 -->服务器给浏览器回复消息
1.响应行:协议版本+\s+状态码+\s+状态码描述
2.响应头:头部字段名:值 (给浏览器看的那些信息)
3.空行
4.响应体,响应正文 (真正显示在浏览器上给用户看的那些数据)
HTTP/1.1 200 OK #响应行:协议版本+状态码+状态码描述Bdpagetype: 2 #响应头 开始Bdqid: 0xf0fb944a00031301Cache-Control: privateConnection: Keep-AliveContent-Encoding: gzipContent-Type: text/html;charset=utf-8Date: Wed, 24 Oct 2018 09:22:04 GMTExpires: Wed, 24 Oct 2018 09:22:04 GMTServer: BWS/1.1Set-Cookie: BDSVRTM=257; path=/Set-Cookie: BD_HOME=1; path=/Set-Cookie: H_PS_PSSID=1433_21080_26350_20930; path=/; domain=.baidu.comStrict-Transport-Security: max-age=172800X-Ua-Compatible: IE=Edge,chrome=1Transfer-Encoding: chunked #响应头 结束#空行#响应正文
3.HTTP请求的方法
#HTTP/1.1协议中共定义了八种方法(也叫“动作”)来以不同方式操作指定的资源:1.GET:向指定的资源发出“显示”请求。使用GET方法应该只用在读取数据,而不应当被用于产生“副作用”的操作中,例如在Web Application中。其中一个原因是GET可能会被网络蜘蛛等随意访问。2.HEAD:与GET方法一样,都是向服务器发出指定资源的请求。只不过服务器将不传回资源的本文部分。它的好处在于,使用这个方法可以在不必传输全部内容的情况下,就可以获取其中“关于该资源的信息”(元信息或称元数据)。3.POST:向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。4.PUT:向指定资源位置上传其最新内容。5.DELETE:请求服务器删除Request-URI所标识的资源。6.TRACE:回显服务器收到的请求,主要用于测试或诊断。7.OPTIONS:这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用'*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。8.CONNECT:HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。注意事项:1.方法名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法的时候,应当返回状态码501(Not Implemented)。2.HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。当然,所有的方法支持的实现都应当匹配下述的方法各自的语义定义。此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法。例如PATCH(由 RFC 5789 指定的方法)用于将局部修改应用到资源。
4.默认端口
1.HTTP默认端口是802.HTTPS默认端口是443
5.常见的状态码
1xx -->请求的消息被接收到等待后续处理2xx -->OK3xx -->重定向4xx -->客户端请求错误5xx -->服务端有问题
6.URL的构成
1.传送协议(http,https)2.层级URL标记符号(为[//]固定不变)3.访问资源需要的凭证信息(可省略)4.服务器(域名,ip)5.端口号(http:80可省略,https:443)6.路径(以'/'字符区别路径中的每一个目录名称)7.查询(get模式的窗体参数,以"?"字符为起点,每个参数以"&"隔开,再以"="分开参数名称与数据,通常以UTF8的URL编码,避开字符冲突问题)8.片段。以"#"字符为起点
7.web框架原理总结
1.收发socket消息(web服务器程序) --> uWsgi,Gunicorn,wsgiref (Nginx和tomcat)
2.WSGI(Web Server Gateway Interface)协议:它定义了使用python编写的web应用程序与web服务器程序之间的接口格式,实现web应用程序与web服务器程序间的解耦
3.业务逻辑不同(web应用程序) --> Django,Flask,Webpy,bottle,Tornado
8.wsgiref简单示例
使用wsgiref收发socket消息
"""根据URL中不同的路径返回不同的内容--函数进阶版返回HTML页面让网页动态起来wsgiref模块版"""import timefrom wsgiref.simple_server import make_server# 将返回不同的内容部分封装成函数def index(url): with open("index.html", "r", encoding="utf8") as f: s = f.read() now = str(time.time()) s = s.replace("@@oo@@", now) return bytes(s, encoding="utf8")def home(url): with open("home.html", "r", encoding="utf8") as f: s = f.read() return bytes(s, encoding="utf8")# 定义一个url和实际要执行的函数的对应关系list1 = [ ("/index/", index), ("/home/", home),]def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None for i in list1: if i[0] == url: func = i[1] break if func: response = func(url) else: response = b"404 not found!" return [response, ]if __name__ == '__main__': httpd = make_server('127.0.0.1', 8090, run_server) print("我在8090等你哦...") httpd.serve_forever()
9.jinja2简单示例
使用jinja2进行字符串替换(渲染html)
用户列表
id值 | 姓名 | 密码 |
---|---|---|
{ {user.od}} | { {user.username}} | { {user.password}} |
from wsgiref.simple_server import make_serverfrom jinja2 import Templatedef index(): with open("index2.html", "r") as f: data = f.read() template = Template(data) # 生成模板文件 ret = template.render({ "name": "Alex", "hobby_list": ["烫头", "泡吧"]}) # 把数据填充到模板里面 return [bytes(ret, encoding="utf8"), ]def home(): with open("home.html", "rb") as f: data = f.read() return [data, ] def userinfo(url): conn = pymysql.connect( host='localhost', port=3306, user='root', password='123' database='db' charset='utf8' ) cursor = conn.cursor(sursor=pymysql.cursors.DictCursor) cursor.execute('select * from userinfo;') user_list = cursor.fetchall() with open('userinfo.html','r',encoding='utf8') as f1: data = f1.read() template = Template(data) msg = template.render({'user_list':user_list}) print(user_list) return bytes(msg,encoding="utf8")# 定义一个url和函数的对应关系URL_LIST = [ ("/index/", index), ("/home/", home), ("/userinfo/",userinfo)]def run_server(environ, start_response): start_response('200 OK', [('Content-Type', 'text/html;charset=utf8'), ]) # 设置HTTP响应的状态码和头信息 url = environ['PATH_INFO'] # 取到用户输入的url func = None # 将要执行的函数 for i in URL_LIST: if i[0] == url: func = i[1] # 去之前定义好的url列表里找url应该执行的函数 break if func: # 如果能找到要执行的函数 return func() # 返回函数的执行结果 else: return [bytes("404没有该页面", encoding="utf8"), ]if __name__ == '__main__': httpd = make_server('', 8000, run_server) print("Serving HTTP on port 8000...") httpd.serve_forever()
从数据库中查询数据以填充页面
conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="xxx", db="xxx", charset="utf8")cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)cursor.execute("select name, age, department_id from userinfo")user_list = cursor.fetchall()cursor.close()conn.close()
创建一个测试的user表
CREATE TABLE user( id int auto_increment PRIMARY KEY, name CHAR(10) NOT NULL, hobby CHAR(20) NOT NULL)engine=innodb DEFAULT charset=UTF8;
小结:模板的原理就是字符串替换,我们只要在HTML页面中遵循jinja2的语法规则写上,其内部就会按照指定的语法进行相应的替换,从而达到动态的返回内容。
10.python中web框架的分类
a.收发socket消息
b.根据不同的url执行不同的函数(业务逻辑)
c.字符串替换(动态网页)
1.第一种分类:(安照上面的三部分功能划分)
1.自行实现b,c;使用第三方的a -->Django
2.自行实现b;使用第三方的a,c -->Flask
3.自行实现a,b,c; -->Tornado
2.第二种分类:
1.Django(大而全)
2.其他
二,Django
1.安装:
命令行安装 1.pip install django == 1.11.16 补充: 1.pip install django == 1.11.16 -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 注意,simple 不能少, 是 https 而不是 http 2.pip install pip -U 设为清华源为默认源 3.python -m pip install --upgrade pip 更新pip 4.pip list 列出当前python解释器下安装的第三方包及其版本信息 5.pip freeze > requirements.txt 将当前pyhton解释器下安装的第三方包信息导出到requirements.txt文件 pip install -r requirements.txt 从指定的requirements.txt文件安装第三方包信息 6.pip uninstall django 卸载另外一种安装方式: PyCharm安装
2.创建Django项目
1.命令行创建 django-admin startproject 项目名2.pyCharm创建 file -> new project -> 左边选django,右边写项目名和选python解释器 注意不要选择使用虚拟环境 打开时选择在新窗口打开
3.运行Django项目
1.命令行 1.切换到项目的目录下 2.python manage.py runserver python manage.py runserver 127.0.0.1:8080 python manage.py runserver 80902.PyCharm 1.先看绿色三角左边的名字和项目名是否一致,一致的化才进行下一步 1.点绿色的三角(注意左侧名称要与项目名相同) 2.edit处设置端口
4.django项目目录
mysite (项目名) -mysite (项目名) -urls.py(函数和函数的对应关系) -settings.py(Django项目的配置信息) -wsgi.py(收发socket消息相关) -manage.py(命令行入口文件) -Template(专门用来html文件的) -static(静态文件css,js) -app(函数)
5.使用Django项目
1.基础必会三件套 1.返回字符串 HttpResponse 2.返回HTML文件 render 3.接受一个url参数,表示跳转到指定的url redirect