tornado是一个轻量级python的web框架,他是非阻塞式的,并且速度很是快.得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒能够处理数以千计的链接,这意味着对于实时 Web 服务来讲,Tornado 是一个理想的 Web 框架。javascript
#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.ioloop import tornado.web class MainHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, world") application = tornado.web.Application([ (r"/index", MainHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()
tornado的路由系统其实就是 url 和 类 的对应关系,这里不一样于其余框架,其余不少框架均是 url 对应 函数,Tornado中每一个url对应的是一个类。css
application = tornado.web.Application([ (r"/index", MainHandler), (r"/story/([0-9]+)", StoryHandler), ]) application.add_handlers('news.baidu.com$', [ (r'/index',NewsHandler), ])
Tornado中原生支持二级域名的路由html
Tornado 的模板支持“控制语句”和“表达语句”,控制语句是使用 {% 和 %} 包起来的 前端
例如 {% if len(items) > 2 %}。java
表达语句是使用 {{ 和 }} 包起来的,python
例如 {{ items[0] }}。web
Tornado控制语句和对应的 Python 语句的格式基本彻底相同。咱们支持 if、for、while 和 try,这些语句逻辑结束的位置须要用 {% end %} 作标记。还经过 extends 和 block 语句实现了模板继承。算法
在使用模板前须要在setting中设置模板路径:"template_path" : "tpl"json
例如:缓存
逻辑语句 <ul> {% for item in list_info %} <li>{{item}}</li> {% end %} </ul> ----------------------------------------- 继承母版 {% block RenderBody %}{% end %} {% block RenderBody %} <h1>Index</h1> 在这里写内容 {% end %} ----------------------------------------- 导入固定的小组件 {% include 'header.html' %}
escape: tornado.escape.xhtml_escape 的別名 xhtml_escape: tornado.escape.xhtml_escape 的別名 url_escape: tornado.escape.url_escape 的別名 json_encode: tornado.escape.json_encode 的別名 squeeze: tornado.escape.squeeze 的別名 linkify: tornado.escape.linkify 的別名 datetime: Python 的 datetime 模组 handler: 当前的 RequestHandler 对象 request: handler.request 的別名 current_user: handler.current_user 的別名 locale: handler.locale 的別名 _: handler.locale.translate 的別名 static_url: for handler.static_url 的別名 xsrf_form_html: handler.xsrf_form_html 的別名
固然了,还能够自定义本身的功能
UIMethod:方便小巧,适合简单的方法
# uimethods.py def tab(self): return 'UIMethod' ------------------------------ 导入和注册 import uimethods as mt settings = { ......, 'ui_methods': mt, } ------------------------------ 使用就很方便了 {{ tab() }} #记住要加()
UIModule:模块化,适合组合模块
from tornado.web import UIModule from tornado import escape class custom(UIModule): def render(self, *args, **kwargs): '''直接返回内容''' def css_files(self): '''返回一个引入式css路径''' def embedded_css(self): '''以字符串的方式返回一个嵌入式的css''' def javascript_files(self): '''返回一个引入式JS路径''' def embedded_javascript(self): '''以字符串的方式返回css语句''' ------------------------------ 导入和注册 import uimodules as md settings = { ......, 'ui_modules': md, } ------------------------------ 使用 {% module custom(123) %} # 能够传参
对于静态文件,能够配置静态文件的目录和前段使用时的前缀,而且Tornaodo还支持静态文件缓存。
在设置中写上:
settings = { 'template_path': 'template', '''模版路径''' 'static_path': 'static', '''实际静态文件路径''' 'static_url_prefix': '/static/', '''静态文件的默认识别前缀,意思是静态文件的路径无论是什么,这要这里写了/static/, 前端无论真实路径,直接用/static/,tornado会自动查找真实路径''' } -------------------------------------------- 前端使用 <link href="/static/example.css" rel="stylesheet" /> 为避免出现前缀修改后前端所有都要修改的状况,还能够用一个方法,使前端能够自动生成路径的前缀 <link href="{{ static_url("example.css") }}" rel="stylesheet" />
Tornado中能够对cookie进行操做,而且还能够对cookie进行签名以放置伪造。
self.set_cookie("mycookie", "myvalue") '''设置cookie''' self.set_secure_cookie("mycookie", "myvalue") '''设置加密cookie''' 设置cookie的时候能够加时间戳参数expires=...,意为到这个时间cookie失效 或者expires_day=3,则过时时间是3天,同时设置的话expires优先级更高 注意:设置加密cookie的时候,需在setting中设置加密签名 settings = { ......, 'cookie_secret':'本身填', } -------------------------------------------- self.get_cookie('mycookie') '''获取cookie''' self.get_secure_cookie('mycookie') '''获取加密cookie'''
签名Cookie的本质是:
写cookie过程:
将值进行base64加密 对除值之外的内容进行签名,哈希算法(没法逆向解析) 拼接 签名 + 加密值
读cookie过程:
读取 签名 + 加密值 对签名进行验证 base64解密,获取值内容
Tornado中的跨站请求伪造和Django中的类似.
设置:
settings = { ... "xsrf_cookies": True, }
使用:
<form action="/new_message" method="post"> {{ xsrf_form_html() }} <input type="text"/> </form> Ajax使用就在本地获取cookie,携带cookie发送请求 _xsrf = getCookie("_xsrf")
装饰器 + Future 从而实现Tornado的异步非阻塞
class AsyncHandler(tornado.web.RequestHandler): @gen.coroutine def get(self): future = Future() future.add_done_callback(self.doing) yield future # 或 # tornado.ioloop.IOLoop.current().add_future(future,self.doing) # yield future def doing(self,*args, **kwargs): self.write('async') self.finish()
当发送GET请求时,因为方法被@gen.coroutine装饰且yield 一个 Future对象,那么Tornado会等待,等待用户向future对象中放置数据或者发送信号,若是获取到数据或信号以后,就开始执行doing方法。
异步非阻塞体如今当在Tornaod等待用户向future对象中放置数据时,还能够处理其余请求。
注意:在等待用户向future对象中放置数据或信号时,此链接是不断开的。
tornado中的请求的一切均可以在self.request中找到.
待定