安装:
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()
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 == '':
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 == '':
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('') # 方式二:
# 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 == "": # 模拟登录成功之后的操作,下面的代码用于注册用户时使用
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()