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:(固然這裏的判斷 能夠經過裝飾來實現) ...