zoukankan      html  css  js  c++  java
  • tornado 基本功能

    Tornado的特点

    Tornado(龙卷风)和Django一样是Python中比较主流的web框架,Tornado 和现在的主流 Web 服务器框架也有着明显的区别:Tornado自带socket,并且实现了异步非阻塞,而且对WebSocket协议天然支持。

    相对于其他Python网络框架,它有如下特点

    • 完整的web框架:与Django、Flask等一样,Tornado也提供URL路由映射、Request上下文、基于模板的页面渲染技术等开发Web应用的必备工具。
    • 是一个高效的网络库,性能与Twisted、Gevent等底层Python框架想媲美:提供了异步I/O支持、超时事件处理。这使得Tornado除了可以作为Web应用服务器框架,还可以用来做爬虫、游戏服务器等后台应用。
    • 提供高效的内部HTTP服务器:虽然其他框架也提供了内部HTTP服务器,但它们的HTTP服务器由于性能原因只能用于测试环境。而Tornado的HTTP服务器与Tornado异步调用紧密结合,可以之间用于生产环境。
    • 完备的websocket支持:WebSocket是HTML5的一种新标准,实现了浏览器与服务器之间的双向实时通信。

    由于Tornado的上述特点,Tornado常被用作大型站点的接口服务框架,而不像Django那样着眼于简历完整的大型网站。

    Tornado的基本组成

    Tonado由 路由系统、视图、模板语言等组成,如果习惯了使用Django你会感觉它功能单薄,但是只有这样才能足够轻量,如果用到什么功能就自己去GitHub上找现成的插件,或者自实现;以下将对这些基本组件进行逐一介绍。

    Django功能概览:
      socket:有 
      中间件:无(使用Python的wsgiref模块)
      路由系统:有
      视图函数:有
      ORM操作:有
      模板语言:有
      simple_tag:有
      cokies:有
      session:有
      csrf:有
      xss:有
      其他:缓存、信号、Form组件、ModelFormm、Admin
    
    tornado功能概览:
      socket:有(异步非阻塞、支持WebScoket)
      路由系统:有
      视图函数:有
      静态文件:有
      ORM操作:无
      模板语言:有
      simple_tag:有,uimethod,uimodule
      cokies:有
      session:无
      csrf:有
      xss:有
      其他:无
    
    Django Tornado
    socket
    路由系统
    视图函数
    静态文件
    模板语言
    ORM操作
    simple_tag 有uimethod,uimodule
    cokies
    session
    csrf
    xss
    其他 缓存、信号、Form组件、ModelFormm、Admin

    Tornado的基本功能

    安装:

    pip install tornado
    

    基本流程

    import tornado.ioloop
    import tornado.web
    
    # 注意继承RequestHandler 而不是redirectHandler
    class MainHandler(tornado.web.RequestHandler):
        
        def get(self):
            """get请求"""
            self.write("Hello World!")
            
    def make_app():
        return tornado.web.Application(
        	[(r"/index", MainHandler), ]		# 路由映射到类
        )
    
    def main():
        app = make_app()	# URL路由映射
        app.listen(8888)	# 创建1个socket对象,监听8888端口
        tornado.ioloop.IOLoop.instance().start()  
        # 启动IOLoop,该函数一直运行且不退出,用于处理完所有客户端的访问请求
        # 相当于conn, addr=socket.accept()进入监听状态
    

    第一步:执行脚本,监听 8888 端口

    第二步:浏览器客户端访问 /index --> http://127.0.0.1:8888/index/

    第三步:服务器接受请求,根据URL的访问映射到RequestHandler的子类,并交由对应的类MainHandler处理该请求

    第四步:MainHandler类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法

    第五步:方法返回值的字符串内容发送浏览器

    配置

    setings={
    'template_path':'templates',	# 配置模板路径
    'static_path':'static',     	# 配置静态文件存放的路径
    'static_url_prefix':'/static/',	 # 在模板中引用静态文件路径时使用的别名 注意是模板引用时的别名,必须以/开头以/结尾
    "xsrf_cookies": True,               # 使用xsrf认证
    'cookie_secret' :'xsseffekrjewkhwy'	# cokies加密时使用的盐
    }
    
    # 加载路由和配置
    application=tornado.web.Application(
        [(r'/login/',LoginHandler) ,	
         (r'/index/',IndexHandler) ,	
        ],		# 参数1 路由系统
        **setings	# 参数2 配置文件
    )
    

    路由系统

    与Django类似,用正则字符串进行路由匹配。有两种:固定字符串路径和参数字符串路径。

    动态路由:

    app=tornado.web.Application(
        [
            (r'^/index/$',MainHandler),
            (r'^/index/(d+)$',MainHandler), #url传参
        ]
    )
    

    域名匹配:

    #支持域名匹配  www.xxx.com:8888/index/333333
    app.add_handlers('www.xxx.com',[
    
            (r'^/index/$', MainHandler),
            (r'^/index/(d+)$', MainHandler),
    ])
    

    反向生成url:

    app.add_handlers('www.zhanggen.com',[
            (r'^/index/$', MainHandler,{},"name1"), #反向生成url
            (r'^/index/(d+)$', MainHandler,{},"name2"),
    ])
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self,*args,**kwargs):
            url1=self.application.reverse_url('name1')
            # reverse_url 反向解析
            url2 = self.application.reverse_url('name2', 666)
            print(url1,url2)
            self.write('hello word')
    

    视图 RequestHandler

    tornado的视图才有CBV模式,url匹配成功之后先 视图执行顺序为 initialize 、prepare、get/post/put/delete、finish;

    接入点函数:需要子类继承并定义具体行为的函数在RequestHandler中被称为接入点函数(Entry Point),例如前面的get()函数就是接入点函数。

    RequestHandler.initialize():

    该方法被子类重写,实现RequestHandler子类实例的初始化过程。可以为该函数传递参数,参数来源于配置URL映射时的定义。

    class ProfileHandler(tornado.web.RequestHandler):
        
        def initialize(self, database):
            self.database = database
            
        def get(self):
            pass
        
    app = tornado.web.Application([(r'/account',ProfileHandler, dict(database="c:\example.db"))])
    
    # initialize有参数database,在定义URL映射时以dict方式给出
    
    RequestHandler.prepare():

    prepare()方法用于调用请求处理(get,post等)方法之前的初始化处理,可以根据实际需求进行重写。通常可以用prepare()方法做资源初始化操作。

    RequestHandler.finish():

    finish()方法用于请求处理结束后的一些清理工作,例如可以做清理对象占用的内存或者关闭数据库连接等。

    RequestHandler.get()/post():

    每个http action在RequestHandler中都已单独的函数进行处理,都是以对应的HTTP方法小写的方式名命。

    • RequestHandler.get(self,*args,**kwargs)
    • RequestHandler.head(self,*args,**kwargs)
    • RequestHandler.post(self,*args,**kwargs)
    • RequestHandler.delete(self,*args,**kwargs)
    • RequestHandler.patch(self,*args,**kwargs)
    • RequestHandler.put(self,*args,**kwargs)
    • RequestHandler.options(self,*args,**kwargs)
    import tornado.ioloop
    import tornado.web
    class MainHandler(tornado.web.RequestHandler):
        def initialize(self): #1
            print()
    
        def prepare(self):
            pass
    
        def get(self,*args,**kwargs):
            self.write('hello word')
    
        def post(self, *args, **kwargs):
            pass
    
        def finish(self, chunk=None):
            pass
            super(self,MainHandler).finish()
    

    请求相关输入捕获

    输入捕获是指在RequestHandler中用于获取客户端输入的工具函数和属性,比如获取url中的参数、post提交的参数等。

    • self.get_argument('user'): 获取GET和POST请求携带的参数

    • self.get_arguments('user_list'):获取GET和POST请求参数列表(如chebox标签和select多选)

    • self.get_query_argument('user'):获取GET请求携带的参数

    • self.get_query_arguments('user_list'):获取GET请求参数列表(如chebox标签和select多选)

    • self.get_body_argument('user'):获取POST请求携带的参数

    • self.get_body_arguments('user_list'):获取POST请求参数列表(如chebox标签和select多选)

    • self.request.body.decode('utf-8'):获取json数据

    • self.get_cookie(name, default=None) : 根据cookie名称获取cookie值

    • self.request :返回itornado.httputil.HTTPServerRequest对象实例的苏醒,通过该对象可以获取关于HTTP请求的一切信息,

      import tornado.web
      
      class DetailHandler(tornado.web.RequestHandler):
          
          def get(self):
              remote_ip = self.request.remote_ip	# 获取客户端的IP地址
              host = self.request.host	# 获取请求的主机地址
              
      

    技巧:在一般情况下 用self.get_argument('user',None)/self.get_arguments('user',None)即可,因为它们不管是GET还是POST,都可以用它们来获取请求携带的参数,相当于是一种合集。

    :以上取值方式如果取不到值就会报错,可以设置取不到值就取None;(例如 self.get_argument('user',None))

    输出响应

    输出响应函数是指一组为客户端生成处理结果的工具函数,扩展url的处理结果。下面列举常用的三种:

    • self.write(chunk): 一般情况下,用于输出字符串到客户端。如果是一个字典,则会以JSON格式发送给客户端,同时将请求头中的Content_type设置成 application/json。
    • self.render(template_name, **kwargs): 用于响应页面,用给定的参数渲染模板,可以在本函数中传入模板文件名称和模板的参数。
    • self.redirect(url,): 重定向页面。

    模板语言

    tornado的模板语言和python语法一致。

    登录示例:

    import tornado.ioloop
    import tornado.web
    
    class LoginHandler(tornado.web.RequestHandler): 
        def get(self):
            self.render('login.html')
    
    settings={
    'template_path':'templates',#配置模板路径
    'static_path':'static',     #配置静态文件存放的路径
    'static_url_prefix':'/static/' #在模板中引用静态文件路径时使用的别名 注意是模板引用时的别名
    }
    app=tornado.web.Application([
                            (r'/login/',LoginHandler) #参数1 路由系统
                                         ],
                            **settings	#参数2 配置文件
                                )
    
    
    if __name__ == '__main__':
        app.listen(8888)     #创建1个socket对象
        tornado.ioloop.IOLoop.instance().start()
    

    html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/static/dist/css/bootstrap.css">
        <title>Title</title>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-5 col-md-offset-3">
                <form method="post" >
                      <div class="form-group">
                        <label for="exampleInputEmail1">用户名</label>
                        <input type="email" class="form-control" id="exampleInputEmail1" placeholder="用户名">
                      </div>
                      <div class="form-group">
                        <label for="exampleInputPassword1">密码</label>
                        <input type="password" class="form-control" id="exampleInputPassword1" placeholder="密码">
                      </div>
                      <button type="submit" class="btn btn-default">提交</button>
                </form>
            </div>
        </div>
    </div>
    </body>
    </html>
    

    引入静态文件

    通过别名引入静态文件:

    <link rel="stylesheet" href="/static/coment.css">
    

    static_url()方式一个如静态文件:

    <link rel="stylesheet" href='{{static_url("dist/css/bootstrap.css") }}'>
    

    通过static_url()方法引入静态文件的好处:

    1、使用static_url()可以不用考虑静态文件修改之后造成引用失效的情况;

    2、还会生成静态文件url会有一个v=...的参数,这是tornado根据静态文件MD5之后的值,如果后台的静态文件修改,这个值就会变化,前端就会重新向后台请求静态文件,保证页面实时更新,不引用浏览器缓存;

    上下文

    如果模板语言中声明了变量,上下文对象必须对应传值,如果没有就设置为空,否则会报错;

    self.render('login.html',**{'erro_msg':'' }) #模板中声明了变量,视图必须传值,如果没有就设置为空;
    
  • 相关阅读:
    save html to local
    Django REST framework¶
    a colorful termial output for phantomjs porting from casperjs
    jespern / djangopiston / wiki / Documentation — Bitbucket
    PyKHTML, a Python interface to KHTML
    phantomjs/examples/echoToFile.js at master · ariya/phantomjs
    Scraping multiple sites in parallel and memory consumption Google Groups
    jQuery Arrays | Create, Add To, Remove From and Compare
    They're hiring based on New Brunswick, NJ, USA
    FudanNLP  java based
  • 原文地址:https://www.cnblogs.com/yzm1017/p/13570756.html
Copyright © 2011-2022 走看看