web----Tornado

 安装:

pip3 install tornado
 
源码安装
https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz

简单入手

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()
import tornado.ioloop
import tornado.web
from tornado import httpclient
from tornado.web import asynchronous
from tornado import gen
# import uimodules as md
# import uimethods as mt
class MainHandler(tornado.web.RequestHandler):
        @asynchronous
        @gen.coroutine              #没测出来效果(这两个装饰器)
        def get(self):
            print('start get ')
            http = httpclient.AsyncHTTPClient()
            http.fetch("https://www.google.com/", self.callback) #利用fetch发送一个异步请求(挂起)
            self.write('end')
        def callback(self, response):
            print(response.body,"---")
settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
    # 'ui_methods': mt,
    # 'ui_modules': md,
}
application = tornado.web.Application([
    (r"/index", MainHandler),
], **settings)

if __name__ == "__main__":
    application.listen(8009)
    tornado.ioloop.IOLoop.instance().start()
异步非堵塞实例

配置静态路径

settings = {
   
'template_path': 'template',
   
'static_path': 'static',
   
'static_url_prefix': '/static/',
   
'cookie_secret': 'sfdsfsdfsdf', #用于给cookie加密的秘钥
}

 加密cookie

签名Cookie的本质是:

写cookie过程:

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

读cookie过程:

  • 读取 签名 + 加密值
  • 对签名进行验证
  • base64解密,获取值内容
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        login_user = self.get_secure_cookie("login_user", None)
        if login_user:
            self.write(login_user)
        else:
            self.redirect('/login')
class LoginHandler(tornado.web.RequestHandler):
    def get(self):
        self.current_user()
        self.render('login.html', **{'status': ''})
    def post(self, *args, **kwargs):
        username = self.get_argument('name')
        password = self.get_argument('pwd')
        if username == 'root' and password == '123':
            self.set_secure_cookie('login_user', '武沛齐')
            self.redirect('/')
        else:
            self.render('login.html', **{'status': '用户名或密码错误'})
settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
    'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh'
}

application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/login", LoginHandler),
], **settings)

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
基于签名cookie用户验证
import tornado.ioloop
import tornado.web
class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("login_user")
class MainHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        login_user = self.current_user
        self.write(login_user)
class LoginHandler(tornado.web.RequestHandler):
    def get(self):
        self.current_user()
        self.render('login.html', **{'status': ''})
    def post(self, *args, **kwargs):
        username = self.get_argument('name')
        password = self.get_argument('pwd')
        if username == 'wupeiqi' and password == '123':
            self.set_secure_cookie('login_user', '武沛齐')
            self.redirect('/')
        else:
            self.render('login.html', **{'status': '用户名或密码错误'})
settings = {
    'template_path': 'template',
    'static_path': 'static',
    'static_url_prefix': '/static/',
    'cookie_secret': 'aiuasdhflashjdfoiuashdfiuh',
    'login_url': '/login'
}
application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/login", LoginHandler),
], **settings)
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
签名cookie实现用户验证

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>
表单提交
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提交

注:Ajax使用时,本质上就是去获取本地的cookie,携带cookie再来发送请求

 上传文件

form表单上传

<form id="my_form" name="form" action="/index" method="POST"  enctype="multipart/form-data" >
        <input name="fff" id="my_file"  type="file" />
        <input type="submit" value="提交"  />
    </form>
html
def post(self, *args, **kwargs):
        file_metas = self.request.files["fff"]
        # print(file_metas)
        for meta in file_metas:
            file_name = meta['filename']
            with open(file_name,'wb') as up:
                up.write(meta['body'])
python后台

ajax上传

<body>
    <input type="file" id="img" />
    <input type="button" onclick="UploadFile();" />
    <script>
        function UploadFile(){
            var fileObj = document.getElementById("img").files[0];

            var form = new FormData();
            form.append("k1", "v1");
            form.append("fff", fileObj);

            var xhr = new XMLHttpRequest();
            xhr.open("post", '/index', true);
            xhr.send(form);
        }
    </script>
</body>
js代码
<body>
    <input type="file" id="img" />
    <input type="button" onclick="UploadFile();" />
    <script>
        function UploadFile(){
            var fileObj = $("#img")[0].files[0];
            var form = new FormData();
            form.append("k1", "v1");
            form.append("fff", fileObj);

            $.ajax({
                type:'POST',
                url: '/index',
                data: form,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
        }
    </script>
</body>
jquery代码

 验证码

待处理

异步非阻塞

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()

httpclient类库

Tornado提供了httpclient类库用于发送Http请求,其配合Tornado的异步非阻塞使用。

import tornado.web
from tornado import gen
from tornado import httpclient
 
# 方式一:
class AsyncHandler(tornado.web.RequestHandler):
    @gen.coroutine
    def get(self, *args, **kwargs):
        print('进入')
        http = httpclient.AsyncHTTPClient()
        data = yield http.fetch("http://www.google.com")
        print('完事',data)
        self.finish('6666')
 
# 方式二:
# class AsyncHandler(tornado.web.RequestHandler):
#     @gen.coroutine
#     def get(self):
#         print('进入')
#         http = httpclient.AsyncHTTPClient()
#         yield http.fetch("http://www.google.com", self.done)
#
#     def done(self, response):
#         print('完事')
#         self.finish('666')
application = tornado.web.Application([
    (r"/async", AsyncHandler),
])
 
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start() 

session组件(原创)

import tornado.web
import tornado.ioloop
import time,hashlib
content = {
}
class Session:
    def create_random_string(self):
        nid = time.time()
        hash_lib = hashlib.md5()
        hash_lib.update(bytes(str(nid), encoding="utf8"))
        return hash_lib.hexdigest()
    def create_session(self):
        self.session_id = self.create_random_string()
        print("chuangjiancookie")
        self.set_cookie("session_id", self.session_id,expires=time.time()+60*7*24)
    def add_content(self,session_id):
        "将session_id添加到content(数据库/本地文件)"
        self.session_id = session_id
        content[self.session_id] = {}
    def add_user(self,username,password):
        "注册成功过了"
        content[self.session_id]["username"]=username
        content[self.session_id]["password"]=password
    def auth_session(self):
        "判断用户是否已经登录"
        session_id = self.get_cookie("session_id")
        if session_id ==None:
            self.create_session()
            return False
        if session_id not in content:
            return False
        else:
            #每次访问网站就会更新cookie时间
            self.set_cookie("session_id",session_id, expires=time.time() + 60 * 5)
            return True
    def __init__(self, *args, **kwargs):
        super().__init__( *args, **kwargs)


class HomeHandler(Session,tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        auth = self.auth_session()
        if auth == False:
            self.redirect("/login")
        else:
            self.write("登录成功")
class LoginHandler(Session,tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        # 验证session
        auth = self.auth_session()
        if auth ==False:
            self.render("login.html")
        if auth == True:
            self.redirect("/home")
    def post(self, *args, **kwargs):
        username = self.get_argument("username")
        password = self.get_argument("password")
        session_id = self.get_cookie("session_id")

        # 从数据库中是否含有root账号,密码是否为password,稍微改一下即可
        if username == "root" and password == "1":

            # 模拟登录成功之后的操作,下面的代码用于注册用户时使用
            self.add_content(session_id)
            self.add_user(username,password)

            self.redirect("/home")
        else:
            self.render("login.html")
settings = {
    "template_path":"template",
    "cookie_secret":"agcgsd"
}
application = tornado.web.Application([
    (r"/login",LoginHandler),
    (r"/home",HomeHandler)
],**settings)

if __name__=="__main__":
    application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()
View Code
原文地址:https://www.cnblogs.com/yanxiaoge/p/10509034.html