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框架的更多相关文章

  1. 【Python之路】第十六篇--Web框架之Tornado

    概述 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了 ...

  2. [Python笔记]第十六篇:web框架之Tornado

    Tornado是一个基于python的web框架,xxxxx 安装 python -m pip install tornado 第一个Tornado程序 安装完毕我们就可以新建一个app.py文件,放 ...

  3. 基于Extjs的web表单设计器 第六节——界面框架设计

    基于Extjs的web表单设计器 基于Extjs的web表单设计器 第一节 基于Extjs的web表单设计器 第二节——表单控件设计 基于Extjs的web表单设计器 第三节——控件拖放 基于Extj ...

  4. 第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础

    第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...

  5. 第三百二十六节,web爬虫,scrapy模块,解决重复ur——自动递归url

    第三百二十六节,web爬虫,scrapy模块,解决重复url——自动递归url 一般抓取过的url不重复抓取,那么就需要记录url,判断当前URL如果在记录里说明已经抓取过了,如果不存在说明没抓取过 ...

  6. 第三百一十六节,Django框架,中间件

    第三百一十六节,Django框架,中间件 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间 ...

  7. 风炫安全web安全学习第三十六节课-15种上传漏洞讲解(一)

    风炫安全web安全学习第三十六节课 15种上传漏洞讲解(一) 文件上传漏洞 0x01 漏洞描述和原理 文件上传漏洞可以说是日常渗透测试用得最多的一个漏洞,因为用它获得服务器权限最快最直接.但是想真正把 ...

  8. 风炫安全WEB安全学习第二十六节课 XSS常见绕过防御技巧

    风炫安全WEB安全学习第二十六节课 XSS常见绕过防御技巧 XSS绕过-过滤-编码 核心思想 后台过滤了特殊字符,比如说

  9. 风炫安全Web安全学习第十六节课 高权限sql注入getshell

    风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...

随机推荐

  1. VMware Workstation的网络连接方式:NAT、桥接和Host Only

    安装完VMware Workstation后会自动生成两个网络连接:VMware Network Adapter VMnet8 和 VMware Network Adapter VMnet1(通常称为 ...

  2. spring作用域(Spring Bean Scopes Example)

    http://docs.spring.io/spring/docs/2.0.x/reference/beans.html#beans-factory-scopes In Spring, bean sc ...

  3. vue 父子组件传值的另外一种方式 provide inject

    1.文档说明 https://cn.vuejs.org/v2/api/#provide-inject 2.实例 element ui的dropdown组件 dropdown.vue: provide( ...

  4. Java之JVM调优案例分析与实战(1) - 高性能硬件上的程序部署策略

    本JVM系列均来源于<深入理解Java虚拟机>一书中,版权归该书作者所有. 环境:一个15万PV/天左右的在线文档类型网站最近更换了硬件系统,新系统硬件为4个CPU.16GB物理内存.OS ...

  5. $.post以后就取不到$(this)节点解决方法【转】

    在作用域开头最好把以后要用的this指针存起来 a.click(function(){ var $this=$(this); $.get("/a").always( $this.v ...

  6. Hibernate持久化对象的状态

    1. 站在持久化的角度 , Hibernate 把对象分为 4 种状态 : 持久化状态, 暂时状态, 游离状态(脱管状态) , 删除状态.Session 的特定方法能使对象从一个状态转换到还有一个状态 ...

  7. TWaver版3D化学元素周期表

    非常早就有人做3D网页版的化学元素周期表了.酷炫效果和新奇技巧一度被众多粉丝奉为神明,争相研究和效仿.甚至有人放弃一切扑向这颗蜡烛.不由总是想到那个OPPO广告女主角拽拽的歧视道:"辞职去旅 ...

  8. 16-spring学习-配置文件操作

    实际使用:配置文件 spring的核心就是一个配置文件.所以只有将表达式应用到配置文件上才会特别有意义. 范例:利用配置文件,编写表达式应用 <bean id="str" c ...

  9. Linux命令-目录处理命令:pwd

    pwd 显示当前目录的绝对路径

  10. JUC组件扩展(三):BlockingQueue(阻塞队列)详解

    一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大 ...