安装:

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

web----Tornado的更多相关文章

  1. python web Tornado框架

    1.Tornado Tornado:python编写的web服务器兼web应用框架 1.1.Tornado的优势 轻量级web框架异步非阻塞IO处理方式出色的抗负载能力优异的处理性能,不依赖多进程/多 ...

  2. Tornado WEB服务器框架 Epoll

    引言: 回想Django的部署方式 以Django为代表的python web应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会 ...

  3. tornado框架&三层架构&MVC&MTV&模板语言&cookie&session

    web框架的本质其实就是socket服务端再加上业务逻辑处理, 比如像是Tornado这样的框架. 有一些框架则只包含业务逻辑处理, 例如Django, bottle, flask这些框架, 它们的使 ...

  4. 框架之Tornado(简单介绍)

    引言 回想Django的部署方式 以Django为代表的python web应用部署时采用wsgi协议与服务器对接(被服务器托管),而这类服务器通常都是基于多线程的,也就是说每一个网络请求服务器都会有 ...

  5. 1.tornado基础

    import tornado.web ''' tornado基础web框架模块 ''' import tornado.ioloop ''' tornado的核心循环IO模块,封装了linux的epol ...

  6. Python3中tornado高并发框架

    1.单线程tornado.web:基础web框架模块tornado.ioloop:核心IO循环模块,高效的基础.封装了:1.asyncio 协程,异步处理2. epoll模型:水平触发(状态改变就询问 ...

  7. 1.(基础)tornado初识

    tornado的话就不带着大家看源码了,今后可能会介绍,目前只是看简单的用法,而且当前的tornado版本不高,其实说白了这是很久以前写的文档,但是由于格式的原因,所以打算用Markdown重写一次. ...

  8. 01@-tornado

    import tornado.web ''' tornado的基础web框架模块 ''' import tornado.ioloop ''' tornado的核心IO循环模块 封装了Linux的epo ...

  9. dota 路人水平鉴定器

    测试的dota水平...目的是学习一下tornado框架 #coding:utf8 import tornado.web,tornado.httpserver,tornado.ioloop,torna ...

  10. Python学习笔记:字符串

    字符串 字符串定义:字符串可以使用一对单引号.双引号或三引号来定义,即便是单个字符也会当做字符串来处理(Python中没有字符类型,单个字符也就是只有一个字符的字符串而已). 原始字符串:字符串中反斜 ...

随机推荐

  1. Arraylist集合遍历输出

    题目:创建一个只能容纳String对象名为names的Arraylist集合,按顺序向集合中添加5个字符串对象.对集合进行遍历,打印出集合中每个元素的位置与内容.首先打印出集合的大小,然后删除集合中的 ...

  2. npm脚本

    在package.json的script里面我们可以写很多npm脚本,下面我来总结一下一些日常遇到的知识点: 1.npm_lifecycle_event npm 提供一个npm_lifecycle_e ...

  3. 即将上线的flume服务器面临的一系列填坑笔记

      即将上线的flume服务器面临的一系列填坑笔记 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   一.flume缺少依赖包导致启动失败! 报错信息如下: 2018-10-17 ...

  4. linux 进程 ctrl-c,ctrl-z,ctrl-d

    linux下: ctrl-c 发送 SIGINT 信号给前台进程组中的所有进程.常用于终止正在运行的程序. ctrl-z 发送 SIGTSTP 信号给前台进程组中的所有进程,常用于挂起一个进程. ct ...

  5. windows上使用mkdocs搭建静态博客

    windows上使用mkdocs搭建静态博客 之前尝试过用HEXO搭建静态博客,最近发现有个叫mkdocs的开源项目也是搭建静态博客的好选择,而且它支持markdown格式,下面简要介绍一下mkdoc ...

  6. DHCP服务洪水攻击

    1.攻击原理 动态主机设置协议是一个局域网的网络协议,使用UDP协议工作,主要有两个用途: 为内部网络或网络服务供应商自动分配IP地址给用户,以作为内部网络管理员对所有计算机做中央管理的手段. 在正常 ...

  7. JS ——document、“或”、event(事件对象)

    1.document <document>是所以HTML的最高节点,比<html>的等级还要高. <document>的第一个子节点是“!”——document.c ...

  8. 20155337 2016-2017-2 《Java程序设计》第七周学习总结

    20155337 2016-2017-2 <Java程序设计>第七周学习总结 教材学习内容总结 •认识时间与日期 •格林威治标准时间:简称GMT时间,参考格林威治皇家天文台的标准太阳时间. ...

  9. setTimeout设置不起作用

    setTimeout立刻调用了 a()方法而不是xx秒以后,是因为调用方法时候没有加双引号. 正确做法:setTimeout(" a() ",5000): 调用 a() 方法时候要 ...

  10. 解决NO migrations to apply

    创建表之后,遇到models模型变动,故当时做了删除应用文件夹下migrations文件,删除后重建,但重建后执行模型合并操作结果为No Changes,无法创建数据表 执行python3 manag ...