第二百五十六节,Web框架
Web框架
Web框架本质
众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。
举例:
#!/usr/bin/env python
#coding:utf-8
import socket #导入单线程通讯模块 def handle_request(client): #发送内容函数
buf = client.recv(1024) #设置最大传输字节
client.sendall(bytes("HTTP/1.1 200 OK\r\n\r\n", encoding='utf-8')) #向客户端发送内容,以字节形式发送
client.sendall(bytes("Hello, World欢迎访问", encoding='utf-8')) #向客户端发送内容 def main(): #创建通讯函数
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建服务端通讯对象
sock.bind(('localhost',8082)) #在服务端设置服务端ip和端口
sock.listen(5) #监听IP和端口,设置一个参数,表示最多连接排队数量 while True: #循环
connection, address = sock.accept() #等待接收客户端的请求,一旦有客户端请求连接,就会返回两个值,一个是连接对象,一个是客户端的地址信息,所以需要两个变量来接收
handle_request(connection) #执行handle_request函数,将客户端请求连接传入handle_request函数
connection.close() #关闭连接 if __name__ == '__main__': #wds系统下if __name__ == "__main__"才能创建进程,我们调试没关系,以后在Linux系统没这个问题
main() #执行main函数
上述通过socket来实现了其本质,而对于真实开发中的python web程序来说,一般会分为两部分:服务器程序和应用程序。服务器程序负责对socket服务器进行封装,并在请求到来时,对请求的各种数据进行整理。应用程序则负责具体的逻辑处理。为了方便应用程序的开发,就出现了众多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的开发方式,但是无论如何,开发出的应用程序都要和服务器程序配合,才能为用户提供服务。这样,服务器程序就需要为不同的框架提供不同的支持。这样混乱的局面无论对于服务器还是框架,都是不好的。对服务器来说,需要支持各种不同框架,对框架来说,只有支持它的服务器才能被开发出的应用使用。这时候,标准化就变得尤为重要。我们可以设立一个标准,只要服务器程序支持这个标准,框架也支持这个标准,那么他们就可以配合使用。一旦标准确定,双方各自实现。这样,服务器可以支持更多支持标准的框架,框架也可以使用更多支持标准的服务器。
所以,对于Web框架来说分为两类,一类是即包含了socket服务端,有包含了逻辑处理,一类是只包含逻辑处理需要另外做socket服务端
python标准库提供的独立WSGI服务器称为wsgiref。
WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,实现web app与web server间的解耦。
wsgiref模块,python标准库提供的独立WSGI服务器称为wsgiref,就是Web框架逻辑处理包含了socket服务端
注意:wsgiref模块在python3以上版本有问题,在2.7上可以使用,所以下面的列子在2.7上运行的
#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server #引入wsgiref的make_server def RunServer(environ, start_response): #创建通讯内容函数
start_response('200 OK', [('Content-Type', 'text/html')]) #HTML方式返回内容
return '<h1>Hello, web!</h1>' #返回内容 if __name__ == '__main__':
httpd = make_server('', 8082, RunServer) #设置访问端口,和通讯内容函数
httpd.serve_forever() #执行通讯函数
RunServer(environ, start_response)创建通讯内容函数,里面有两个参数
environ里面包含用户的请求信息如ip等
start_response里面包含返回信息
查看方式:
自定义Web框架
一、框架
通过python标准库提供的wsgiref模块开发一个自己的Web框架
根据用户访问的路径,给出相应的内容
#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server def index(): #函数返回字符串index
return 'index' def login(): #login
return 'login' URLS = { #设置一个字典,键为路径名称,值为函数名称
"/index":index,
"/login":login,
} def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO'] #接收用户访问的路径名称
if url in URLS.keys(): #判断用户访问路径在URLS字典里是否存在
furl = URLS[url] #如果存在通过下标拿到字典里的函数名称
ret = furl() #执行函数赋值给ret变量,相当于ret等于函数返回字符串
else:
ret = "" #如果不存在ret变量等于404
return ret #最后将ret变量返回给浏览器 if __name__ == '__main__':
httpd = make_server('', 8082, RunServer)
httpd.serve_forever()
二、模板引擎,和MVC
MVC框架,就是归类后根据文件夹定义的名字
在上一步骤中,对于所有的login、index均返回给用户浏览器一个简单的字符串,在现实的Web请求中一般会返回一个复杂的符合HTML规则的字符串,所以我们一般将要返回给用户的HTML写在指定文件中,然后再返回。如:
模板引擎归类,归类就是为了以后方便管理
urls.py将映射文件信息写在这个文件里,以后要添加映射就在这里写
#!/usr/bin/env python
#coding:utf-8
import controller
# 映射文件
URLS = { #设置一个字典,键为路径名称,值为函数名称
"/index":controller.index,
"/login":controller.login,
}
controller.py逻辑处理文件,根据用户访问路径,给出对应的处理,以后要添加逻辑处理函数就写在这里
#!/usr/bin/env python
#coding:utf-8
import os #引入os模块 # 映射文件对应的函数
def index(): #函数返HTML文件内容
f = open(os.path.join('views','index.html'),'r') #拼接路径,打开index.html
data = f.read() #读出html文件内容
f.close() #关闭打开的文件
return data def login():
f = open(os.path.join('views', 'login.html'),'r')
data = f.read()
f.close()
return data
start.py模板引擎启动文件,用于启动模板引擎,一般不做修改
#!/usr/bin/env python
#coding:utf-8
from wsgiref.simple_server import make_server #导入wsgiref模块里的make_server方法
from urls import URLS #导入映射文件变量 def RunServer(environ, start_response): #定义RunServer函数,接收请求信息,和发送内容
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO'] #接收用户访问的路径名称
if url in URLS.keys(): #判断用户访问路径在URLS字典里是否存在
furl = URLS[url] #如果存在通过下标拿到字典里的函数名称
ret = furl() #执行函数赋值给ret变量,相当于ret等于函数返回字符串
else:
ret = "" #如果不存在ret变量等于404
return ret #最后将ret变量返回给浏览器 if __name__ == '__main__':
httpd = make_server('', 8082, RunServer)
httpd.serve_forever()
views文件夹用于专门存放html文件
models文件夹用于专门存放数据库处理文件
整理后的结构
Web框架,一般根据存放数据库处理文件夹的首字母M,存放html文件夹首字母V,逻辑处理文件首字母C,来命名的,这就是mvc框架
Web框架运行图
Web框架请求动态内容
对于上述代码,虽然可以返回给用户HTML的内容以现实复杂的页面,但是还是存在问题:如何给用户返回动态内容?
1自定义一套特殊的语法,进行替换
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--{{item}}设置一个表示-->
<h1>{{item}}</h1>
</body>
</html>
逻辑处理文件controller.py
#!/usr/bin/env python
#coding:utf-8
import os #引入os模块
import time #引入事件模块
# 映射文件对应的函数
def index(): #函数返HTML文件内容
f = open(os.path.join('views','index.html'),'r') #拼接路径,打开index.html
data = f.read() #读出html文件内容
f.close() #关闭打开的文件
new_data = data.replace("{{item}}",str(time.time())) #获取系统时间转换成字符串,替换html里的{{item}}
return new_data def login():
f = open(os.path.join('views', 'login.html'),'r')
data = f.read()
f.close()
return data
2使用开源工具jinja2,遵循其指定语法
jinja2模块Web框架模块
Template()方法逻辑处理Web框架
render()方法设置html可调用python变量
encode()返回逻辑处理后的网页字符串给浏览器
首先需要安装jinja2第三方模块
逻辑处理文件controller.py
#!/usr/bin/env python
#coding:utf-8
import os #引入os模块
from jinja2 import Template #引入jinja2模块
# 映射文件对应的函数
def index(): #函数返HTML文件内容
f = open(os.path.join('views','index.html'),'r') #拼接路径,打开index.html
result = f.read() #读出html文件内容
f.close() # 关闭打开的文件
template = Template(result) #将读出的字符串传入jinja2模块的Template方法逻辑处理网页字符串
data = template.render(name='John Doe', user_list=['alex', 'eric']) #render方法向网页字符串添加python可以变量
return data.encode('utf-8') #返回逻辑处理后的字符串给浏览器 def login():
f = open(os.path.join('views', 'login.html'),'r')
data = f.read()
f.close()
return data
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{name}}</h1> <!--{{引用框架逻辑处理设置变量}}--> <ul>
{% for item in user_list %} <!--{%可以远行代码块%}-->
<li>{{item}}</li>
{% endfor %}
</ul>
</body>
</html>
第二百五十六节,Web框架的更多相关文章
- 【Python之路】第十六篇--Web框架之Tornado
概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...
- [Python笔记]第十六篇:web框架之Tornado
Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放 ...
- 基于Extjs的web表单设计器 第六节——界面框架设计
基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...
- 第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础
第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...
- 第三百二十六节,web爬虫,scrapy模块,解决重复ur——自动递归url
第三百二十六节,web爬虫,scrapy模块,解决重复url——自动递归url 一般抓取过的url不重复抓取,那么就需要记录url,判断当前URL如果在记录里说明已经抓取过了,如果不存在说明没抓取过 ...
- 第三百一十六节,Django框架,中间件
第三百一十六节,Django框架,中间件 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间 ...
- 风炫安全web安全学习第三十六节课-15种上传漏洞讲解(一)
风炫安全web安全学习第三十六节课 15种上传漏洞讲解(一) 文件上传漏洞 0x01 漏洞描述和原理 文件上传漏洞可以说是日常渗透测试用得最多的一个漏洞,因为用它获得服务器权限最快最直接.但是想真正把 ...
- 风炫安全WEB安全学习第二十六节课 XSS常见绕过防御技巧
风炫安全WEB安全学习第二十六节课 XSS常见绕过防御技巧 XSS绕过-过滤-编码 核心思想 后台过滤了特殊字符,比如说
- 风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...
随机推荐
- OJ帐号保存
TOJ 614173971 HDU 宇智波佐助 POJ shiai ZOJ henyumen UVa henyumen Light OJ HENYUMEN bzoj henyumen ural 165 ...
- Qt 5.3更新无数,更改C++控制台输出最为赞
迁移至 多色网
- windows bat启动多个应用程序
windows bat启动多个应用程序 CreationTime--2018年7月26日11点02分 Author:Marydon 1.应用场景 每天开机后,都需要打开平常所需要的软件,又不想将程 ...
- 【Linux】od命令
用途 od命令主要用于查看非文本文件,通过指定该命令的不同选项可以以十进制.八进制.十六进制和ASCII码来显示 全称 od的全称为:Octal Dump 参数 -t :后面接各种类型的显示方式 a ...
- python selenium 自动化测试环境安装
注意:2.7和3.0版本的语法有些不一样 安装自动化测试软件 selenium(地址http://www.seleniumhq.org/download/) 安装步骤: 1.安装pythone运行环境 ...
- android中checkbox的padding引发的问题
自己定义checkbox中的勾选框图标.这次由于想偷懒.图标弄的大了些.然后一系列的问题就都引出来了. 1.图标比checkbox的layout_height高.看不见了. 非常吐血吧,Compoun ...
- 抛弃鼠标的神器——Vimium
j: 向下细微滚动窗口. k:向上细微滚动窗口.(默认的<c-e><c-y> 表示Ctrl+e,按住ctrl再按e,<c-y>同理.在此感谢[Gnat] ht ...
- 面面具到!android重力传感器
前两篇都是向大家介绍了很有意思的两种手势操作,嵌入我们游戏中,不得不说让游戏的自由度.可玩性和趣味性都增色不少!那么今天继续给大家介绍一亮点!传感器! 一:什么是传感器: 所谓传感器能够探测如光.热. ...
- python 操作redis之——HyperLogLog (八)
#coding:utf8 import redis # python 操作redis之——HyperLogLog r =redis.Redis(host=") # 1.Pfadd 命令将所有 ...
- ERRORS:<class 'Salesman.admin.UsrMngUserAdmin'>: (admin.E005) Both 'fieldsets' and 'fields' are specified.
在使用django admin的过程中 遇到了这个错误 . Both 'fieldsets' and 'fields' are specified. django.core.management.ba ...