zoukankan      html  css  js  c++  java
  • Tornado的使用

    Tornado是非阻塞式web服务器,另外,Tornado还是一个支持WebSocket的优秀框架

    `pip3 install tornado`

    快速开始

    #!/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是一个非阻塞的web服务器以及web框架,但是在使用的时候只有使用异步的库才会真正发挥它异步的优势,因为异步的库返回的是Future对象

    在3.0版本之后,gen.coroutine模块显得比较突出。coroutine装饰器可以让本来靠回调的异步编程看起来像同步编程。

    其中便是利用了Python中生成器的Send函数。在生成器中,yield关键字往往会与正常函数中的return相比。它可以被当成迭代器,从而使用next()返回yield的结果。

    但是生成器还有另外一个用法,就是使用send方法。在生成器内部可以将yield的结果赋值给一个变量,而这个值是通过外部的生成器client来send的

    import tornado.ioloop
    import tornado.web
    from tornado.httpclient import AsyncHTTPClient
    from tornado import gen
    
    
    class MainHandler(tornado.web.RequestHandler):
        @gen.coroutine
        def get(self):
            client = AsyncHTTPClient()
            resp = yield client.fetch("https://www.baidu.com")  # 必须用异步的模块
            if resp.code == 200:
                self.write(str(resp))
            else:
                self.write("Fail")
            
    
    application = tornado.web.Application([
        (r"/index", MainHandler),
    ])
    
    if __name__ == "__main__":
        application.listen(8009)
        tornado.ioloop.IOLoop.instance().start()

    路由系统

    路由系统其实就是 url 和 类 的对应关系,这里不同于其他框架,其他很多框架均是 url 对应 函数,Tornado中每个url对应的是一个类。

    #!/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")
       
    class StoryHandler(tornado.web.RequestHandler):
        def get(self, story_id):
            self.write("You requested the story " + story_id)
       
    class BuyHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("buy.wupeiqi.com/index")
       
    application = tornado.web.Application([
        (r"/index", MainHandler),
        (r"/story/([0-9]+)", StoryHandler),
    ])
       
    application.add_handlers('buy.wupeiqi.com$', [
        (r'/index',BuyHandler),
    ])
       
    if __name__ == "__main__":
        application.listen(80)
        tornado.ioloop.IOLoop.instance().start()
    二级路由代码

     

    静态文件

    settings = {
        'template_path': 'template',    # 定义模板根目录
        'static_path': 'jingtai',        # 定义静态文件根目录,使用:"/static/xx.jpg"
        'static_url_prefix': '/jt/',     # 使用:"/jt/xx.jpg"
    }

    模板引擎

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("index.html", list_info = [11,22,33], k='a1')

    渲染变量:{{   }}

    条件语句:{% if len(items) > 2 %} ... {% else %} .... {% end %}

    循环:{% for item in list_info %}    {{ item }}  {%  end %}

    css、js渲染: 

    <link href="{{static_url("css/common.css")}}" rel="stylesheet" />
    <script src="{{static_url("js/jquery-1.8.2.min.js")}}"></script>

    其他方法:

    在模板中默认提供了一些函数、字段、类以供模板使用:
    
    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 的別名

     模板复用:

    header.html

    <div>
        <ul>
            <li>USA</li>
            <li>51区</li>
        </ul>
    </div>

    使用:{%  include  'header.html'  %}

    模板继承:

    ############## layout.html #################
    <!DOCTYPE html>
    <html>
    <head>
        ....
        {% block CSS %}{% end %}
        ....
    </head>
    <body>
    
       ......
        
        {% block RenderBody %} {% end %}
       
        .......
        {% block JavaScript %}{% end %}
    </body>
    </html>
    {% extends 'layout.html'%}
    {% block CSS %}
        <link href="{{static_url("css/index.css")}}" rel="stylesheet" />
    {% end %}
    
    {% block RenderBody %}
        <h1>Index</h1>
        <ul>
        {%  for item in li %}
            <li>{{item}}</li>
        {% end %}
        </ul>
    
    {% end %}
    
    {% block JavaScript %}
        ..
    {% end %}

    自定义UIMethod以UIModule

      类似于django的自定义标签(定义-注册-使用)

    from tornado.web import UIModule
    from tornado import escape
    
    
    """1. 定义"""
    ################ uimodules.py ###############
    class custom(UIModule):
        def render(self, *args, **kwargs):
            return escape.xhtml_escape('<h1>wupeiqi</h1>')
    ############################################
    
    ################ uimethod.py ###############
    def tab(self):
        return 'UIMethod'
    ############################################
    
    """2. 注册"""
    import uimodules as md
    import uimethods as mt
    
    settings = {
        'ui_methods': mt,
        'ui_modules': md,
    }
    
    
    """3. 使用"""
    '''
    {% module custom(123) %}
    {{ tab() }}
    '''

    CSRF

    settings = {
        "xsrf_cookies": True,
    }
    application = tornado.web.Application([
        (r"/", MainHandler),
        (r"/login", LoginHandler),
    ], **settings)

    使用:普通表单

    <form action="/new_message" method="post">
      {{ xsrf_form_html() }}
      <input type="text" name="message"/>
      <input type="submit" value="Post"/>
    </form>
    普通表单使用

    使用:ajax

    function getCookie(name) {
        var r = document.cookie.match("\b" + name + "=([^;]*)\b");
        return r ? r[1] : undefined;
    }
    
    jQuery.postJSON = function(url, args, callback) {
        args._xsrf = getCookie("_xsrf");
        $.ajax({url: url, data: $.param(args), dataType: "text", type: "POST",
            success: function(response) {
            callback(eval("(" + response + ")"));
        }});
    };
    ajax使用

    cookie

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            if not self.get_cookie("mycookie"):
                self.set_cookie("mycookie", "myvalue")
                self.write("Your cookie was not set yet!")
            else:
                self.write("Your cookie was set!")
    cookie基本操作

    cookie加密

    Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息,你需要对 cookie 作签名以防止伪造。

    Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法,你需要在创建应用时提供一个密钥,名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中:

    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            if not self.get_secure_cookie("mycookie"):
                self.set_secure_cookie("mycookie", "myvalue")
                self.write("Your cookie was not set yet!")
            else:
                self.write("Your cookie was set!")
                 
    application = tornado.web.Application([
        (r"/", MainHandler),
    ], cookie_secret="61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=")
    签名cookie的使用

    签名Cookie的本质是:

    写cookie过程:

    • 将值进行base64加密
    • 对除值以外的内容进行签名,哈希算法(无法逆向解析)
    • 拼接 签名 + 加密值

    读cookie过程:

    • 读取 签名 + 加密值
    • 对签名进行验证
    • base64解密,获取值内容

    form表单+iframe实现局部刷新

    11

  • 相关阅读:
    configparser模块
    xml文件解析
    shutil模块 + shelve模块 二合一版
    hashlib模块
    subprocess模块和sys模块
    re模块
    os模块
    random模块
    time模块、datetime模块讲解
    洛谷P3414 SAC#1
  • 原文地址:https://www.cnblogs.com/staff/p/13149946.html
Copyright © 2011-2022 走看看