安装:

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. 【CSS】绝对定位和相对定位

    html:定位层 特点: >>完全脱离默认文档流,独立于立体层面的Z轴之上. >>和float浮动一样都脱离了默认文档流,但float元素与默认文档流之间会相互产生影响,而定位 ...

  2. Python基础【day01】:初始模块(五)

    本节内容 1.标准库 1.sys 2.os 2.第三方库 1.for mac 2.for linux Python的强大之处在于他有非常丰富和强大的标准库和第三方库,几乎你想实现的任何功能都有相应的P ...

  3. JavaEE学习总结(十六)— Servlet

    一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向 ...

  4. python---ORM之SQLAlchemy(4)relationship多对多练习

    练习一:朋友 import sqlalchemy from sqlalchemy import create_engine from sqlalchemy import Column, String, ...

  5. servlet 获取 post body 体用流读取为空的问题【转】

    引用自: http://www.zicheng.net/article/982028.htm 目前基于rest风格的很多API开始使用通过body data来传输来代替之前的key-value传输方式 ...

  6. MySQL与宿主Linux之间交互式执行命令

    在MySQL里面执行Linux的命令并返回结果 system commands root@localhost 11:36:23> system cal March 2017 Su Mo Tu W ...

  7. CSS——margin

    CSS margin 属性 定义和用法 margin 简写属性在一个声明中设置所有外边距属性.该属性可以有 1 到 4 个值. 说明 这个简写属性设置一个元素所有外边距的宽度,或者设置各边上外边距的宽 ...

  8. CSS —— 选择器

    选择器种类 标签选择器 id选择器 类选择器 通配符 交集选择器 并集选择器 后代选择器 子代选择器 选择器设置样式优先级 默认样式 < 继承样式 < 通配符设置样式 < 标签选择器 ...

  9. MacOs -bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory

    1解决iterm远程登录主机报错 -bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or ...

  10. MHA-Failover(GTID,Auto_Position=0)

    最近一位同学遇到的案例:凌晨数据库意外宕机,要求在一主两从的基础上,搭建MHA做故障切换.在部署测试中遇到一些问题找到我,交流的过程挖出一些之前忽略的坑,感谢这位同学无私分享!• GTID环境,KIL ...