湖南省重点建设项目办公室网站,在哪个网站上找国外客户做外贸,昆明网站开发培训,中劵资本集团股票交易网站建设中tornado简介
1、tornado概述
Tornado就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本。Tornado 和现在的主流 Web 服务器框架#xff08;包括大多数 Python 的框架#xff09;有着明显的区别#xff1a;它是非阻塞式服务器#xff0c;而且速度相当快。得利于…tornado简介
1、tornado概述
Tornado就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本。Tornado 和现在的主流 Web 服务器框架包括大多数 Python 的框架有着明显的区别它是非阻塞式服务器而且速度相当快。得利于其 非阻塞的方式和对epoll的运用Tornado 每秒可以处理数以千计的连接因此 Tornado 是实时 Web 服务的一个 理想框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。关于如何扩容 服务器以处理数以千计的客户端的连接的问题请参阅The C10K problem
Tornado代表嵌入实时应用中最新一代的开发和执行环境。 Tornado 包含三个完整的部分
1、Tornado系列工具 一套位于主机或目标机上强大的交互式开发工具和使用程序
2、VxWorks 系统 目标板上高性能可扩展的实时操作系统;
3、可选用的连接主机和目标机的通讯软件包 如以太网、串行线、在线仿真器或ROM仿真器。
2、tornado特点
Tornado的独特之处在于其所有开发工具能够使用在应用开发的任意阶段以及任何档次的硬件资源上。而且完整集的Tornado工具可以使开发人员完全不用考虑与目标连接的策略或目标存储区大小。Tornado 结构的专门设计为开发人员和第三方工具厂商提供了一个开放环境。已有部分应用程序接口可以利用并附带参考书目内容从开发环境接口到连接实现。Tornado包括强大的开发和调试工具尤其适用于面对大量问题的嵌入式开发人员。这些工具包括C和C源码级别的调试器目标和工具管理系统目标跟踪内存使用分析和自动配置. 另外所有工具能很方便地同时运行很容易增加和交互式开发。
3、tornado模块索引
最重要的一个模块是web 它就是包含了 Tornado 的大部分主要功能的 Web 框架。其它的模块都是工具性质的 以便让 web 模块更加有用 后面的 Tornado 攻略 详细讲解了 web 模块的使用方法。
主要模块
web - FriendFeed 使用的基础 Web 框架包含了 Tornado 的大多数重要的功能escape - XHTML, JSON, URL 的编码/解码方法database - 对 MySQLdb 的简单封装使其更容易使用template - 基于 Python 的 web 模板系统httpclient - 非阻塞式 HTTP 客户端它被设计用来和 web 及 httpserver 协同工作auth - 第三方认证的实现包括 Google OpenID/OAuth、Facebook Platform、Yahoo BBAuth、FriendFeed OpenID/OAuth、Twitter OAuthlocale - 针对本地化和翻译的支持options - 命令行和配置文件解析工具针对服务器环境做了优化
底层模块
httpserver - 服务于 web 模块的一个非常简单的 HTTP 服务器的实现iostream - 对非阻塞式的 socket 的简单封装以方便常用读写操作ioloop - 核心的 I/O 循环
tornado框架使用
1、安装tornado
pip install tornado
源码安装https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz2、先写一个入门级的代码吧相信大家都能看懂声明tornado内部已经帮我们实现socket。
#!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.web
import tornado.ioloopclass IndexHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write(Hello World, My name is 张岩林)application tornado.web.Application([(r/index,IndexHandler),
])if __name__ __main__:application.listen(8080)tornado.ioloop.IOLoop.instance().start()第一步执行脚本监听 8080 端口
第二步浏览器客户端访问 /index -- http://127.0.0.1:8080/index
第三步服务器接受请求并交由对应的类处理该请求
第四步类接受到请求之后根据请求方式post / get / delete …的不同调用并执行相应的方法
第五步然后将类的方法返回给浏览器
tornado路由系统
在tornado web框架中路由表中的任意一项是一个元组,每个元组包含pattern(模式)和handler(处理器)。当httpserver接收到一个http请求server从接收到的请求中解析出url path(http协议start line中)然后顺序遍历路由表如果发现url path可以匹配某个pattern则将此http request交给web应用中对应的handler去处理。
由于有了url路由机制web应用开发者不必和复杂的http server层代码打交道只需要写好web应用层的逻辑(handler)即可。Tornado中每个url对应的是一个类。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
__auth__ zhangyanlinimport tornado.web
import tornado.ioloopclass IndexHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write(Hello World, My name is 张岩林)class LoginHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write(input type text)class RegisterHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.write(input type password)application tornado.web.Application([(r/index/(?Ppage\d*),IndexHandler), # 基础正则路由(r/login,LoginHandler),(r/register,RegisterHandler),
])# 二级路由映射
application.add_handlers(buy.zhangyanlin.com$,[(r/login, LoginHandler),
])if __name__ __main__:application.listen(8080)tornado.ioloop.IOLoop.instance().start()观察所有的网页的内容下面都有分页当点击下一页后面的数字也就跟着变了这种就可以用基础正则路由来做下面我来给大家下一个网页分页的案例吧 #!/usr/bin/env python
# -*- coding:utf-8 -*-
__auth__ zhangyanlinimport tornado.web
import tornado.ioloopLIST_INFO [{username:zhangyanlin,email:133164.com}
]
for i in range(200):temp {username:str(i)zhang,email:str(i)163.com}LIST_INFO.append(temp)class Pagenation:def __init__(self,current_page,all_item,base_url): #当前页 内容总数 目录try:page int(current_page)except:page 1if page 1:page 1all_page,c divmod(all_item,5)if c 0:all_page 1self.current_page pageself.all_page all_pageself.base_url base_urlpropertydef start(self):return (self.current_page - 1) * 5propertydef end(self):return self.current_page * 5def string_pager(self):list_page []if self.all_page 11:s 1t self.all_page 1else:if self.current_page 6:s 1t 12else:if (self.current_page 5) self.all_page:s self.current_page-5t self.current_page 6else:s self.all_page - 11t self.all_page 1first a href /index/1首页/alist_page.append(first)# 当前页if self.current_page 1:prev a href javascript:void(0):上一页/aelse:prev a href /index/%s上一页/a%(self.current_page-1,)list_page.append(prev)#页码for p in range(s,t):if p self.current_page:temp a class active href /index/%s%s/a%(p,p)else:temp a href /index/%s%s/a % (p, p)list_page.append(temp)# 尾页if self.current_page self.all_page:nex a href javascript:void(0):下一页/aelse:nex a href /index/%s下一页/a % (self.current_page 1,)list_page.append(nex)last a href /index/%s尾页/a%(self.all_page)list_page.append(last)#跳转jump input typetexta onclick Jump(%s,this);GO/a%(/index/)script scriptfunction Jump(baseUrl,ths){var val ths.previousElementSibling.value;if (val.trim().length 0){location.href baseUrl val;}}/scriptlist_page.append(jump)list_page.append(script)str_page .join(list_page)return str_pageclass IndexHandler(tornado.web.RequestHandler):def get(self, page):obj Pagenation(page,len(LIST_INFO),/index/)current_list LIST_INFO[obj.start:obj.end]str_page obj.string_pager()self.render(index.html, list_infocurrent_list, current_pageobj.current_page, str_pagestr_page)application tornado.web.Application([(r/index/(?Ppage\d*),IndexHandler)])if __name__ __main__:application.listen(8080)tornado.ioloop.IOLoop.instance().start()tornado服务端demo !DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlestyle.pager a{display: inline-block;padding: 5px 6px;margin: 10px 3px;border: 1px solid #2b669a;text-decoration:none;}.pager a.active{background-color: #2b669a;color: white;}/style
/head
bodyh3显示数据/h3table border1theadtrth用户名/thth邮箱/th/tr/theadtbody{% for line in list_info %}trtd{{line[username]}}/tdtd{{line[email]}}/td/tr{% end %}/tbody/tablediv classpager{% raw str_page %}/div
/body
/html前端HTML文件
注两个文件必须放在同一个文件夹下中间前端代码中有用到XSS攻击和模板语言这两个知识点下面会详细解释
tornado 模板引擎
Tornao中的模板语言和django中类似模板引擎将模板文件载入内存然后将数据嵌入其中最终获取到一个完整的字符串再将字符串返回给请求者。
Tornado 的模板支持“控制语句”和“表达语句”控制语句是使用 {% 和 %} 包起来的 例如 {% if len(items) 2 %}。表达语句是使用 {{ 和 }} 包起来的例如 {{ items[0] }}。
控制语句和对应的 Python 语句的格式基本完全相同。我们支持 if、for、while 和 try这些语句逻辑结束的位置需要用 {% end %} 做标记。还通过 extends 和 block 语句实现了模板继承。这些在 template 模块 的代码文档中有着详细的描述。
注在使用模板前需要在setting中设置模板路径“template_path” : “views”
settings {template_path:views, #设置模板路径设置完可以把HTML文件放置views文件夹中static_path:static, # 设置静态模板路径设置完可以把cssJSJquery等静态文件放置static文件夹中static_url_prefix: /sss/, #导入时候需要加上/sss/例如script src/sss/jquery-1.9.1.min.js/scriptcookie_secret: asdasd, #cookie生成秘钥时候需提前生成随机字符串需要在这里进行渲染xsrf_cokkies:True, #允许CSRF使用
}application tornado.web.Application([ (r/index,IndexHandler),
],**settings) #需要在这里加载文件目录结构如下: 1、模板语言基本使用for循环if…else使用,自定义UIMethod以UIModule #!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web
import uimodule as md
import uimethod as mtINPUT_LIST []
class MainHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):name self.get_argument(xxx,None)if name:INPUT_LIST.append(name)self.render(index.html,npm NPM88888,xxoo INPUT_LIST)def post(self, *args, **kwargs):name self.get_argument(xxx)INPUT_LIST.append(name)self.render(index.html, npm NPM88888, xxoo INPUT_LIST)# self.write(Hello, World!!!)settings {template_path:tpl, # 模板路径的配置static_path:statics, # 静态文件路径的配置ui_methods:mt, # 自定义模板语言ui_modules:md, # 自定义模板语言
}#路由映射路由系统
application tornado.web.Application([(r/index,MainHandler),
],**settings)if __name__ __main__:# 运行socketapplication.listen(8000)tornado.ioloop.IOLoop.instance().start()start.py from tornado.web import UIModule
from tornado import escapeclass custom(UIModule):def render(self, *args, **kwargs):return 张岩林uimodule def func(self,arg):return arg.lower()uimethod !DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlelink typetext/css relstylesheet hrefstatic/commons.css
/head
bodyscript srcstatic/zhang.js/scripth1Hello world/h1h1My name is zhangyanlin/h1h1输入内容/h1form action/index methodpostinput typetext namexxxinput typesubmit value提交/formh1展示内容/h1h3{{ npm }}/h3h3{{ func(npm)}}/h3h3{% module custom() %}/h3ul{% for item in xxoo %}{% if item zhangyanlin %}li stylecolor: red{{item}}/li{% else %}li{{item}}/li{% end %}{% end %}/ul
/body
/htmlindex.html
2、母板继承
(1)、相当于python的字符串格式化一样先定义一个占位符 !DOCTYPE html
html
headmeta http-equivContent-Type contenttext/html; charsetUTF-8/title帅哥/titlelink href{{static_url(css/common.css)}} relstylesheet /{% block CSS %}{% end %}
/head
bodydiv classpg-header/div{% block RenderBody %}{% end %}script src{{static_url(js/jquery-1.8.2.min.js)}}/script{% block JavaScript %}{% end %}
/body
/htmllayout.html
(2)、再子板中相应的位置继承模板的格式 {% extends layout.html%}
{% block CSS %}link href{{static_url(css/index.css)}} relstylesheet /
{% end %}{% block RenderBody %}h1Index/h1ul{% for item in li %}li{{item}}/li{% end %}/ul{% end %}{% block JavaScript %}{% end %}index.html
3、导入内容 divulli张岩林帅/lili张岩林很帅/lili张岩林很很帅/li/ul
/divcontent.html !DOCTYPE html
html
headmeta http-equivContent-Type contenttext/html; charsetUTF-8/title张岩林/titlelink href{{static_url(css/common.css)}} relstylesheet /
/head
bodydiv classpg-header{% include header.html %}/divscript src{{static_url(js/jquery-1.8.2.min.js)}}/script/body
/htmlindex.html
在模板中默认提供了一些函数、字段、类以供模板使用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 的別名当你制作一个实际应用时你会需要用到 Tornado 模板的所有功能尤其是 模板继承功能。所有这些功能都可以在template 模块 的代码文档中了解到。其中一些功能是在 web 模块中实现的例如 UIModules
tornado cookie
Cookie有时也用其复数形式Cookies指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据通常经过加密。定义于RFC2109和2965都已废弃最新取代的规范是RFC6265。可以叫做浏览器缓存
1、cookie的基本操作 #!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.ioloop
import tornado.webclass MainHandler(tornado.web.RequestHandler):def get(self):print(self.cookies) # 获取所有的cookieself.set_cookie(k1,v1) # 设置cookieprint(self.get_cookie(k1)) # 获取指定的cookieself.write(Hello, world)application tornado.web.Application([(r/index, MainHandler),
])if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()2、加密cookie签名
Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息你需要对 cookie 作签名以防止伪造。Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法你需要在创建应用时提供一个密钥名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中
#!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.ioloop
import tornado.webclass MainHandler(tornado.web.RequestHandler):def get(self):if not self.get_secure_cookie(mycookie): # 获取带签名的cookieself.set_secure_cookie(mycookie, myvalue) # 设置带签名的cookieself.write(Your cookie was not set yet!)else:self.write(Your cookie was set!)
application tornado.web.Application([(r/index, MainHandler),
])if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()签名Cookie的本质是
写cookie过程将值进行base64加密对除值以外的内容进行签名哈希算法无法逆向解析拼接 签名 加密值读cookie过程读取 签名 加密值对签名进行验证base64解密获取值内容用cookie做简单的自定义用户验证下面会写一个绝对牛逼的自定义session用户验证 #!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.ioloop
import tornado.webclass BaseHandler(tornado.web.RequestHandler):def get_current_user(self):return self.get_secure_cookie(login_user)class MainHandler(BaseHandler):tornado.web.authenticateddef get(self):login_user self.current_userself.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 张岩林 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: zhangyanlinhaoshuai,
}application tornado.web.Application([(r/index, MainHandler),(r/login, LoginHandler),
], **settings)if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()自定义验证登录
3、JavaScript操作Cookie
由于Cookie保存在浏览器端所以在浏览器端也可以使用JavaScript来操作Cookie。
/*
设置cookie指定秒数过期
name表示传入的key
value表示传入相对应的value值
expires表示当前日期在加5秒过期*/function setCookie(name,value,expires){var temp [];var current_date new Date();current_date.setSeconds(current_date.getSeconds() 5);document.cookie name value ;expires current_date.toUTCString();
}注jQuery中也有指定的插件 jQuery Cookie 专门用于操作cookie猛击这里
4、自定义session
本来这想新开一个帖子但是还是把代码贴在这吧有用到session验证的时候直接复制拿走就好 #!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.web
import tornado.ioloopcontainer {}
class Session:def __init__(self, handler):self.handler handlerself.random_str Nonedef __genarate_random_str(self):import hashlibimport timeobj hashlib.md5()obj.update(bytes(str(time.time()), encodingutf-8))random_str obj.hexdigest()return random_strdef __setitem__(self, key, value):# 在container中加入随机字符串# 定义专属于自己的数据# 在客户端中写入随机字符串# 判断请求的用户是否已有随机字符串if not self.random_str:random_str self.handler.get_cookie(__session__)if not random_str:random_str self.__genarate_random_str()container[random_str] {}else:# 客户端有随机字符串if random_str in container.keys():passelse:random_str self.__genarate_random_str()container[random_str] {}self.random_str random_str # self.random_str asdfasdfasdfasdfcontainer[self.random_str][key] valueself.handler.set_cookie(__session__, self.random_str)def __getitem__(self, key):# 获取客户端的随机字符串# 从container中获取专属于我的数据# 专属信息【key】random_str self.handler.get_cookie(__session__)if not random_str:return None# 客户端有随机字符串user_info_dict container.get(random_str,None)if not user_info_dict:return Nonevalue user_info_dict.get(key, None)return valueclass BaseHandler(tornado.web.RequestHandler):def initialize(self):self.session Session(self)自定义session
XSS攻击和CSRF请求伪造
XSS
跨站脚本攻击(Cross Site Scripting)为不和层叠样式表(Cascading Style Sheets, CSS)的缩写混淆故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码当用户浏览该页之时嵌入其中Web里面的Script代码会被执行从而达到恶意攻击用户的特殊目的。
tornado中已经为我们给屏蔽了XSS但是当我们后端向前端写前端代码的时候传入浏览器是字符串而不是形成代码格式。所以就需要一个反解在传入模板语言中前面加一个raw例如{{ raw zhangyanlin }},这样通俗的讲可能不太懂写一段代码可能就懂了 class IndexHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):jump input typetexta onclick Jump(%s,this);GO/a%(/index/)script scriptfunction Jump(baseUrl,ths){var val ths.previousElementSibling.value;if (val.trim().length 0){location.href baseUrl val;}}/scriptself.render(index.html,jumpjump,scriptscript) #传入两个前端代码的字符串start.py !DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlestyle.pager a{display: inline-block;padding: 5px;margin: 3px;background-color: #00a2ca;}.pager a.active{background-color: #0f0f0f;color: white;}/style
/head
bodydiv classpager{% raw jump %}{% raw script%}/div
/body
/html index.html
CSRF
CSRFCross-site request forgery跨站请求伪造也被称为“one click attack”或者session riding通常缩写为CSRF或者XSRF是一种对网站的恶意利用。尽管听起来像跨站脚本XSS但它与XSS非常不同并且攻击方式几乎相左。XSS利用站点内的信任用户而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比CSRF攻击往往不大流行因此对其进行防范的资源也相当稀少和难以防范所以被认为比XSS更具危险性。 当前防范 XSRF 的一种通用的方法是对每一个用户都记录一个无法预知的 cookie 数据然后要求所有提交的请求中都必须带有这个 cookie 数据。如果此数据不匹配 那么这个请求就可能是被伪造的。
Tornado 有内建的 XSRF 的防范机制要使用此机制你需要在应用配置中加上 xsrf_cookies 设定xsrf_cookiesTrue再来写一段代码来表示一下 #!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.web
import tornado.ioloopclass CsrfHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.render(csrf.html)def post(self, *args, **kwargs):self.write(张岩林已经收到客户端发的请求伪造)settings {template_path:views,static_path:statics,xsrf_cokkies:True, # 重点在这里往这里看
}application tornado.web.Application([(r/csrf,CsrfHandler)
],**settings)if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()start.py !DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/title
/head
bodyform action/csrf methodpost{% raw xsrf_form_html() %}pinput nameuser typetext placeholder用户//ppinput namepwd typetext placeholder密码//pinput typesubmit valueSubmit /input typebutton valueAjax CSRF onclickSubmitCsrf(); //formscript src/statics/jquery-1.12.4.js/scriptscript typetext/javascriptfunction ChangeCode() {var code document.getElementById(imgCode);code.src ?;}function getCookie(name) {var r document.cookie.match(\\b name ([^;]*)\\b);return r ? r[1] : undefined;}function SubmitCsrf() {var nid getCookie(_xsrf);$.post({url: /csrf,data: {k1: v1,_xsrf: nid},success: function (callback) {// Ajax请求发送成功有自动执行// callback服务器write的数据 callback“csrf.post”console.log(callback);}});}/script
/body
/htmlcsrf.html
简单来说就是在form验证里面生成了一段类似于自己的身份证号一样携带着他来访问网页
tornado上传文件
上传文件这块可以分为两大类第一类是通过form表单验证进行上传还有一类就是通过ajax上传下面就来介绍一下这两类
1、form表单上传文件 #!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.web
import tornado.ioloop
import osclass IndexHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.render(index.html)def post(self, *args, **kwargs):file_metas self.request.files[filename] # 获取文件信息for meta in file_metas: file_name meta[filename] # 获得他的文件名字file_names os.path.join(static,img,file_name)with open(file_names,wb) as up: # 打开本地一个文件up.write(meta[body]) # body就是文件内容把他写到本地settings {template_path:views,static_path:static,static_url_prefix: /statics/,
}application tornado.web.Application([(r/index,IndexHandler)
],**settings)if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()start.py !DOCTYPE html
html langen
headmeta charsetUTF-8title上传文件/title
/head
bodyform action/index methodpost enctypemultipart/form-datainput typefile name filenameinput typesubmit value提交/form
/body
/htmlindex.html
2、ajax上传文件 !DOCTYPE html
html
head lang enmeta charsetUTF-8title/title
/head
bodyform idmy_form nameform action/index methodPOST enctypemultipart/form-data div idmaininput namefilename idmy_file typefile /input typebutton nameaction valueUpload onclickredirect()/iframe idmy_iframe namemy_iframe src classhide/iframe/div/formscriptfunction redirect(){document.getElementById(my_iframe).onload Testt;document.getElementById(my_form).target my_iframe;document.getElementById(my_form).submit();}function Testt(ths){var t $(#my_iframe).contents().find(body).text();console.log(t);}/script
/body
/htmlHTML iframe !DOCTYPE html
html
head langenmeta charsetUTF-8title/title
/head
bodyinput typefile idimg /input typebutton onclickUploadFile(); value提交/script src/statics/jquery-1.12.4.js/scriptscriptfunction UploadFile(){var fileObj $(#img)[0].files[0];var form new FormData();form.append(filename, fileObj);$.ajax({type:POST,url: /index,data: form,processData: false, // tell jQuery not to process the datacontentType: false, // tell jQuery not to set contentTypesuccess: function(arg){console.log(arg);}})}/script
/body
/htmlJquery 上传 !DOCTYPE html
html
head langenmeta charsetUTF-8title/title
/head
bodyinput typefile idimg /input typebutton onclickUploadFile(); value提交 /scriptfunction UploadFile(){var fileObj document.getElementById(img).files[0];var form new FormData();form.append(filename, fileObj);var xhr new XMLHttpRequest();xhr.open(post, /index, true);xhr.send(form);}/script
/body
/htmlXML提交 #!/usr/bin/env python
# -*- coding:utf-8 -*-import tornado.web
import tornado.ioloop
import osclass IndexHandler(tornado.web.RequestHandler):def get(self, *args, **kwargs):self.render(index.html)def post(self, *args, **kwargs):file_metas self.request.files[filename] # 获取文件信息for meta in file_metas:file_name meta[filename] # 获得他的文件名字file_names os.path.join(static,img,file_name)with open(file_names,wb) as up: # 打开本地一个文件up.write(meta[body]) # body就是文件内容把他写到本地settings {template_path:views,static_path:static,static_url_prefix: /statics/,
}application tornado.web.Application([(r/index,IndexHandler)
],**settings)if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()start.py
注下面所有的实例用相同的python代码都能实现只需要改前端代码python代码文件名为start.py
tornado 生成随机验证码
用python生成随机验证码需要借鉴一个插件和一个io模块实现起来也非常容易当然也需要借鉴session来判断验证码是否错误下面写一段用户登录验证带验证码的再看下效果插件必须和执行文件必须放在更目录下 #!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.web
import tornado.ioloopcontainer {}
class Session:def __init__(self, handler):self.handler handlerself.random_str Nonedef __genarate_random_str(self):import hashlibimport timeobj hashlib.md5()obj.update(bytes(str(time.time()), encodingutf-8))random_str obj.hexdigest()return random_strdef __setitem__(self, key, value):# 在container中加入随机字符串# 定义专属于自己的数据# 在客户端中写入随机字符串# 判断请求的用户是否已有随机字符串if not self.random_str:random_str self.handler.get_cookie(__session__)if not random_str:random_str self.__genarate_random_str()container[random_str] {}else:# 客户端有随机字符串if random_str in container.keys():passelse:random_str self.__genarate_random_str()container[random_str] {}self.random_str random_str # self.random_str asdfasdfasdfasdfcontainer[self.random_str][key] valueself.handler.set_cookie(__session__, self.random_str)def __getitem__(self, key):# 获取客户端的随机字符串# 从container中获取专属于我的数据# 专属信息【key】random_str self.handler.get_cookie(__session__)if not random_str:return None# 客户端有随机字符串user_info_dict container.get(random_str,None)if not user_info_dict:return Nonevalue user_info_dict.get(key, None)return valueclass BaseHandler(tornado.web.RequestHandler):def initialize(self):self.session Session(self)class LoginHandler(BaseHandler):def get(self, *args, **kwargs):self.render(login.html ,state )def post(self, *args, **kwargs):username self.get_argument(username)password self.get_argument(password)code self.get_argument(code)check_code self.session[CheckCode]if username zhangyanlin and password 123 and code.upper() check_code.upper():self.write(登录成功)else:self.render(login.html,state 验证码错误)class CheckCodeHandler(BaseHandler):def get(self, *args, **kwargs):import ioimport check_codemstream io.BytesIO()img,code check_code.create_validate_code()img.save(mstream,GIF)self.session[CheckCode] codeself.write(mstream.getvalue())settings {template_path:views,cookie_secret: asdasd,
}application tornado.web.Application([(r/login,LoginHandler),(r/check_code,CheckCodeHandler)
],**settings)if __name__ __main__:application.listen(8888)tornado.ioloop.IOLoop.instance().start()start.py !DOCTYPE html
html langen
headmeta charsetUTF-8title验证码/title
/head
bodyform action/login methodpostp用户名: input typetext nameusername /pp密码: input typepassword namepassword /pp验证码: input typetext namecodeimg src/check_code onclickChangeCode(); id checkcode/pinput typesubmit valuesubmit span{{state}}/span/form
script typetext/javascript //当点击图片的时候会刷新图片这一段代码就可以实现function ChangeCode() {var code document.getElementById(checkcode);code.src ?;}
/script
/body
/htmllogin.html
效果图如下 插件下载地址猛击这里