1 基本概念
像其余web框架同样, tornado也包括了如下内容:css
基本构成: a 路由系统 b 视图 获取请求数据 返回数据 c 模板语言 模板基本使用 自定义函数 利用组件本身完成 分页, 中间件等扩展功能
概念html
Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本。python
这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过为了能有效利用非阻塞式服务器环境,这个 Web 框架还包含了一些相关的有用工具 和优化。web
特色flask
Tornado 和如今的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,并且速度至关快。后端
得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒能够处理数以千计的链接。浏览器
对于实时 Web 服务来讲,Tornado 是一个理想的 Web 框架。
开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每个活动用户都会保持着一个服务器链接。(关于如何扩容 服务器,以处理数以千计的客户端的链接的问题,请参阅 C10K problem。)服务器
2 简单应用
(1) 登陆页面的小实例:cookie
import tornado.ioloop import tornado.web class LoginHandler(tornado.web.RequestHandler): def get(self): self.render('login.html') # 渲染template settings = { 'template_path':'templates', 'static_path':'static', 'static_url_prefix':'/stat/', # 静态文件 url } # 配置模板文件路径 application = tornado.web.Application( [(r"/login",LoginHandler),],**settings # 配置文件 ) if __name__ == '__main__': # 建立socket对象 application.listen(8001) # conn,add = socket.accept() tornado.ioloop.IOLoop.instance().start() # 1 执行脚本,监听 8000 端口 # 2 浏览器客户端访问 /index --> http://127.0.0.1:8000/index # 3 服务器接受请求,并交由对应的类处理该请求 # 4 类接受到请求以后,根据请求方式(post / get / delete ...)的不一样调用并执行相应的方法 # 5 方法返回值的字符串内容发送浏览器
像Django中的app
{% load static from staticfiles %} {% static 'main.css'% }
flask中
{{url_for('static',filename='main.css')}}
tornado 也支持 静态文件的反向查找
{{static_url('main.css')}}
(2) csrf 配置
settings = { 'xsrf_cookies':True } {% raw xsrf_from_html() %} # 使用
(3) 请求数据
self.get_query_argument('page') # get params数据 self.get_body_argument('username') # post form数据 self.get_argument('username') self.get_argument('page') # 全部数据均可以获取 def post(self): usrname = self.get_argument('username') pwd = self.get_argument('pwd') print(usrname,pwd) if usrname == 'root' and pwd == '123': self.redirect('http://google.com') return self.write('post')
(4) 模板语言
self.render('login.html',**{'msg':'用户密码有误'}) self.render('index.html',user_list=user_list,user_dict=user_dict) python 语法: {{msg}} #注意: msg为空,在后端也得声明 msg = '' <ul> {% for item in user_list %} <li>{{item}}</li> {% end %} </ul> {{ user_list[0] }} {{ user_dict['id'] }} {{ user_dict.get('name') }}
(5) cookie设置
**普通cookie** self.set_cookie('user',username) self.get_cookie('user') **加密cookie** 设置 settings = { 'cookie_secret':'salt' } self.set_secure_cookie('user',username) self.get_secure_cookie('user',username)
代码实例:
import tornado.ioloop import tornado.web class LoginHandler(tornado.web.RequestHandler): def get(self): self.render('login.html',msg='') # 渲染template def post(self): username = self.get_argument('username') pwd = self.get_argument('pwd') if username == 'root' and pwd == '123': self.set_cookie('user',username) self.redirect('/index') return self.render('login.html',**{'msg':'用户密码有误'}) class IndexHandler(tornado.web.RequestHandler): def get(self): if self.get_cookie('user'): user_list = [ 'james','kobe' ] user_dict = { 'id':1,'name':'cp3' } self.render('index.html',user_list=user_list,user_dict=user_dict) return # 直接 return 返回(推荐写法) self.redirect('/login') settings = { 'template_path':'templates', 'static_path':'static', 'static_url_prefix':'/stat/', # 静态文件 url # 'xsrf_cookies':True, # csrf } # 配置模板文件路径 application = tornado.web.Application([ (r"/login",LoginHandler), (r"/index",IndexHandler), ],**settings # 配置文件 ) if __name__ == '__main__': # 建立socket对象 application.listen(8000) # conn,add = socket.accept() tornado.ioloop.IOLoop.instance().start()
(6) 经过tornado请求入口,在请求处理前,封装一些数据
class AuthHandler(tornado.web.RequestHandler): def initialize(self): self.username = self.get_secure_cookie('user') # 初始化的时候 def prepare(self): pass # 执行_excute 方法 class LoginHandler(AuthHandler): # @cookie_auth 判断self.username 是否有值 def get... if self.username:(固然这里的判断 能够经过装饰来实现) ...