python_tornado
1、创建Tornado服务器
1、创建Application对象
Application是Torando最核心的类
所有关于服务器的配置信息都写在Application构造器中
以构造器的参数形式传入,比如路由列表
路由列表的作用告诉Tornado,对特定路径的请求,由哪个类进行响应
app = Application([('/',IndexHandler)])
2、创建真正的服务器程序
server = HTTPServer(app)
3、让服务器监听某一个端口
server.listen(8888)
4、当前线程中启动服务器
IOLoop.current().start()
5、创建一个响应类,继承自RequestHandler,
对请求的方式(get/post),调用重写父类的get/post
class IndexHandler(RequestHandler):
def get(self, *args, **kwargs):
self.write('hello tornado')
def post(self, *args, **kwargs):
pass
2、对程序中可能经常变化的值应该提取到配置文件中
1、创建文件夹,在文件夹中创建file,充当配置文件
PORT = 9999
2、在源代码中引用
define('变量名',type=类型,default=默认值)
parse_config_file('配置文件所在的路径')
options.变量名
示例:
define('PORT',type=int,default=8888)
parse_config_file('../config/config')
server.listen(options.PORT)
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.options import define, parse_config_file, options
from tornado.web import Application, RequestHandler
class IndexHandler(RequestHandler):
def get(self, *args, **kwargs):
self.write('<a href=/java>java</a><br>')
self.write('<a href=/python>python</a>')
def post(self, *args, **kwargs):
pass define('PORT',type=int,default=8888)
parse_config_file('../config/config') class PythonHandler(RequestHandler):
def get(self, *args, **kwargs):
self.write('<a href=/java> goto java</a>') class JavaHandler(RequestHandler):
def get(self, *args, **kwargs):
self.write('hello java') #1、创建application对象
app = Application([('/',IndexHandler),
('/python',PythonHandler),
('/java',JavaHandler)])
#2、创建真正的tornado服务器
server = HTTPServer(app)
#3、设置监听端口
server.listen(options.PORT)
#4、启动服务器
IOLoop.current().start()
3、如果对路由列表中不存在的路径发起请求,会得到404:Not Found
4、Python中,带有HTML标签的字符串也仅仅是一个普通的字符串,但是将这样的字符串作为服务器的响应交给客户端时,
客户端会进行解析,渲染后呈现给客户,客户端(浏览器)会根据HTML标签做不同的渲染处理
5、可以利用正则表达式匹配具有一定规律的所有的路径,路径的具体内容会以参数的形式传入get/post方法,
参数名称可以随意指定,但是最好给参数之默认值,一般默认值为None
6、利用get_body_argument 或 get_body_arguments可以获取请求体中的参数get_body_argument获得的是单独的参数值( 最后一个参数)
get_body_arguments获得的是列表形式的参数值,
另外两者存在明显的区别
1、使用get_body_argument时,最好提供默认值,防止访问时没有提供服务器需要的参数导致400:bad request.
使用get_body_arguments时,如果客户端没有提供服务器需要的参数,只会获得一个空列表,不会产生错误
2、如果在请求体中存在重名的参数,get_body_argument仅能取到最后一个设置的参数值,而get_body_arguments可以取得所有的 重名的键所对应的值
7、界面的跳转:self.redirect("路径")
8、利用get_query_argument 或get_query_arguments可以获得以get方式发起请求时携带的参数,
前者获取的是单独的参数值,后者获得的是以列表的形式组成的参数值,两者的区别
同get_body_arguments
9、利用get_argument获取请求参数,就像get_query_argument + get_body_arguments,无论请求参数是出现在请
行中还是请求体中,只要有该参数就能获取到该参数值,首先获取请求行中的参数在获取请求体中的参数
10、RquestHandler里面有一个属性,叫做request,引用一个HttpServerRequest类型的对象,
该对象中封装了与请求相关的几乎一切内容,我们可以利用self.requset.headers获取所有请求头,
headers是以字典的方式组织请求头中的名和值,可以利用self.request.files获取上传文件,
files也是以字典的形式组织上传的文件,每一个上传文件都有3个属性:
1、type属性,表示文件的类型(例如png/jpeg)
2、filename属性,表示文件的文件名称
3、body属性,表示二进制的文件内容
4、通过标准额IO操作,就可以将上传的文件保存到服务器
1、框架作者通过“钩子方法”将框架中的代码和使用者的代码结合起来,完成一个复杂的业务
在Tornado框架中,从截获请求到生成响应中间有很多步骤,Tornado作者设置了若干个钩子方法供使用者根据具体业务需要重写:
钩子方法包括:
set_default_headers:设置默认响应头
initialize:接收路由列表初始化参数
get/post:生成响应内容
on_finish:释放或关闭资源
钩子方法没有必要非得重写
2、
调用set_header("头名","值")设置默认响应头
调用set_status(状态码,'状态码描述')设置响应(状态码)
注意:HTTP协议中不存的状态码,要手动给出状态描述,否则会产生500错误,在实际开发中谨慎用HTTP协议中不存在的状态码
调用send_error(状态码)触发write_error方法产生错误信息,
说明:write_error方法是父类方法,如果要改写,注意要调用父类方法的原有逻辑
3、服务器两种常见的响应格式
1、JSON字符串
操作步骤1:
1、构建一个Python字典,然后将字典转为JSON字符串,
2、设置响应头中Content-Type的值为application/json;charset=UTF-8
3、将JSON字符串作为服务器的响应交给客户端
操作步骤1:
1、构建一个Python字典
2、然后直接将字典作为服务器的响应交给客户端
3、说明:Tonado帮助我们完成了从Python字典到JSON字符串的转换工作
2、HTML页面(模板)
4、模板的使用
1、创建一个存放模板文件的文件夹,(比如:mytemplate)
2、在模板文件夹下创建HTML文件充当模板
3、在Tornado中配置模板路径,在Application构造器中以关键字template_path传入路径(比如:template_path='mytemplate')
4、使用模板self.render('模板文件的名字')
注意:render是将作为模板的HTML页面转为字符串,再将字符串作为服务器的响应交给客户端
5、
在模板中,可以使用{{}}插入变量,算术表达式或函数表达式(内置的函数表达式,或者自定义的函数表达式),
但是,必须在render方法中对模板中使用的变量,算术表达式的变量以及函数表达式中的自定义函数进行赋值,
不然会产生500错误
注意:render传递的变量不是以字典的形式,self.render("blog.html",a=50,b=500)
6、在模板中。可以使用{%%}插入语句
循环语句{% for 循环结果 in 可迭代对象 %} ... {% end %}
注意:
1、可迭代对象也是一个变量,对负责render,谁就要给可迭代对象赋值
2、语句结束时,只需要写{% end %},Tornado会进行就近匹配原则进行匹配
分支语句{% if 条件 %} ...{% else %} ... {% end %}
7、在模板中,使用静态资源
1、创建存放静态资源的文件夹,比如mystatic,将各种静态资源(图片,CSS,JS)分子文件夹存入mystatic
2、配置静态资源的路径,配置方式就是在Application的构造器中添加参数:static_path = “mystatic”
3、使用静态资源
1、方式一:需要静态资源的地方写static/子文件夹/静态资源文件名称
示例:static/images/xxx.jpg
2、方式二:使用Tornado的内置函数,构建静态资源的路径{{static_url('静态资源的路径')}}
示例:{{static_url('images/xxx.jpg')}}
static是Tornado中的关键字,Tornado会根据static_path来解析static
8、块的使用
为了减少写各个子模板时重复代码的书写,就把各个子模板中相同内容提取到一个公共模块中(一般公共模板的名字都为base.html)
各个子模板通过继承公共模板{% extends base.html %}就可以获得这些相同的内容
在写公共模板时,要使用语句块{% block 块名称%}标示出各个子模板可能不同的地方,这样以后再写子模板时,只要关注各个子模板不同的地方即可
9、模块的使用
1、在模板文件夹(mytemplate)下创建模块文件夹,用来存放模块文件
2、在模块文件夹下,创建模块文件
3、在模块文件中需要使用模块文件的位置,插入语句:{% module xxx()%} xxx是用来将模块文件转为(render)一个字符串插入到模板文件中
4、配置Application,利用关键字ui_modules进行传参,参数是字典,{"xxx":自定义module类}
5、创建自定义module类继承自UIModule类,重写父类中的钩子方法render,render方法一定要返回一个字符串,该字符串就是插入模板中的
内容,一般该字符串是根据要使用的模块文件生成的,从模块文件到字符串只需要调用父类的render_string方法就可以完成
注意:如果模块文件中包含变量,变量表达式,自定义函数表达式,一定在调用render_string方法时,对变量或自定义函数赋值。
使用模块的意义:
并不在于让模板变得简洁,使用模块的意义在于模块是可以复用的,构建新的页面时,是可以使用已有模块进行皮娜姐组成,而不用在从头构建
10、Tornado的自动转义
Tornado针对<script></script>会默认开启自动转义功能,以防止恶意代码的执行
所谓的转义就是将<script>标签变为<script>
如果要关闭该功能,有两种方式:
1、在Application的构造器中某一关键字传参autoescape传入,值None,会影响到所有模板中的HTML文件都关闭转义
2、在需要关闭自动转义的页面中加入语句:{% autoescape None %}
需要注意的是,Google Chrome浏览器安全级别比较高,即使Tornado关闭了转义,Chrome浏览器依然会拦截<script>
标签的文本的执行,可以通过设置响应头来压制Chrome的安全机制:set_header("X-XSS-Protection",0)
11、如何快速学习网络框架
从以下三点:
1、如何配置路由
2、如何使用模板
3、如何加载静态资源
python_tornado的更多相关文章
随机推荐
- C语言I博客作业04
这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-1/homework/9773 我在这个课程的目标 ...
- C++学习笔记7_多态
1. 类与类之间的关系class A{ public: int a; void funcA() {}}包含: class B { public: void funcB(){} A a; }//如果类B ...
- 学习笔记63_python反射
####反射预备知识一########### __call__ 对象后面加括号,触发执行. python中,类的默认的内置方法,有一个名为__call__,如 class foo: def __in ...
- 使用float设置经典的网站前端结构(深入探讨)
.要是DIV的子元素宽度大于它自己的宽度,不管子元素有没有脱离文档流,子元素会在横向向右溢出. 关于高度:1.要是DIV的高度没有设定,其高度受“没有脱离文档流”的子元素影响.以下是DIV宽度为0的情 ...
- 论文阅读 Prefetch-aware fingerprint cache management for data deduplication systems
论文链接 https://link.springer.com/article/10.1007/s11704-017-7119-0 这篇论文试图解决的问题是在cache 环节之前,prefetch-ca ...
- Linux下修改文件权限,所有权
Linux与Unix是多用户操作系统,所以文件的权限与所有权的实现就显得很有必要:每个文件主要与三组权限打交道,分别是用户(user),用户组(group),其他用户(other) 用户(u)是文件的 ...
- 前端与算法 leetcode 283. 移动零
目录 # 前端与算法 leetcode 283. 移动零 题目描述 概要 提示 解析 解法一:暴力法 解法二:双指针法 算法 传入[0,1,0,3,12]的运行结果 执行结果 GitHub仓库 # 前 ...
- [考试反思]0727NOIP模拟测试9
啊哈?水到一个rk1? 谢谢诸位大佬放水让我这种人体验到了rk1的滋味. 怪怪的滋味.不太像我的水平. 其实这次考试心态已经佛了,刚意识到前6次考试累计的挺高的分数被清空了,7,8两场又爆炸了... ...
- 使用Typescript重构axios(十四)——实现拦截器
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 股票交易——单调队列优化DP
题目描述 思路 蒟蒻还是太弱了,,就想到半个方程就GG了,至于什么单调队列就更想不到了. $f[i][j]$表示第$i天有j$张股票的最大收益. 那么有四种选择: 不买股票:$f[i][j]=max( ...