真诚为民 發表於 2016-7-28 09:13:00

浅析tornado web框架

<h1>tornado简介</h1>
<p>&nbsp;</p>
<p><strong><span style="font-size: 16px">1、tornado概述</span></strong></p>
<p>Tornado就是我们在 FriendFeed 的 Web 服务器及其常用工具的开源版本。Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对epoll的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。我们开发这个 Web 服务器的主要目的就是为了处理 FriendFeed 的实时功能 ——在 FriendFeed 的应用里每一个活动用户都会保持着一个服务器连接。(关于如何扩容 服务器,以处理数以千计的客户端的连接的问题,请参阅The C10K problem)</p>
<p>Tornado代表嵌入实时应用中最新一代的开发和执行环境。 Tornado 包含三个完整的部分:</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; (1)、Tornado系列工具, 一套位于主机或目标机上强大的交互式开发工具和使用程序;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(2)、VxWorks 系统, 目标板上高性能可扩展的实时操作系统;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; (3)、可选用的连接主机和目标机的通讯软件包 如以太网、串行线、在线仿真器或ROM仿真器。</p>
<p><strong><span style="font-size: 16px">2、tornado特点</span></strong></p>
<p><span style="font-size: 16px">Tornado的独特之处在于其所有开发工具能够使用在应用开发的任意阶段以及任何档次的硬件资源上。而且,完整集的Tornado工具可以使开发人员完全不用考虑与目标连接的策略或目标存储区大小。Tornado 结构的专门设计为开发人员和第三方工具厂商提供了一个开放环境。已有部分应用程序接口可以利用并附带参考书目,内容从开发环境接口到连接实现。Tornado包括强大的开发和调试工具,尤其适用于面对大量问题的嵌入式开发人员。这些工具包括C和C++源码级别的调试器,目标和工具管理,系统目标跟踪,内存使用分析和自动配置. 另外,所有工具能很方便地同时运行,很容易增加和交互式开发。</span></p>
<p id="_1"><strong><span style="font-size: 16px">3、tornado模块索引</span></strong></p>
<p>最重要的一个模块是<code>web</code>, 它就是包含了 Tornado 的大部分主要功能的 Web 框架。其它的模块都是工具性质的, 以便让&nbsp;<code>web</code>&nbsp;模块更加有用 后面的&nbsp;Tornado 攻略&nbsp;详细讲解了&nbsp;<code>web</code>&nbsp;模块的使用方法。</p>
<p id="_2"><strong><span style="font-size: 16px">主要模块</span></strong></p>
<ul>
<li><code>web</code>&nbsp;- FriendFeed 使用的基础 Web 框架,包含了 Tornado 的大多数重要的功能</li>
<li><code>escape</code>&nbsp;- XHTML, JSON, URL 的编码/解码方法</li>
<li><code>database</code>&nbsp;- 对&nbsp;<code>MySQLdb</code>&nbsp;的简单封装,使其更容易使用</li>
<li><code>template</code>&nbsp;- 基于 Python 的 web 模板系统</li>
<li><code>httpclient</code>&nbsp;- 非阻塞式 HTTP 客户端,它被设计用来和&nbsp;<code>web</code>&nbsp;及&nbsp;<code>httpserver</code>&nbsp;协同工作</li>
<li><code>auth</code>&nbsp;- 第三方认证的实现(包括 Google OpenID/OAuth、Facebook Platform、Yahoo BBAuth、FriendFeed OpenID/OAuth、Twitter OAuth)</li>
<li><code>locale</code>&nbsp;- 针对本地化和翻译的支持</li>
<li><code>options</code>&nbsp;- 命令行和配置文件解析工具,针对服务器环境做了优化</li>
</ul>
<p id="_3"><strong><span style="font-size: 16px">底层模块</span></strong></p>
<ul>
<li><code>httpserver</code>&nbsp;- 服务于&nbsp;<code>web</code>&nbsp;模块的一个非常简单的 HTTP 服务器的实现</li>
<li><code>iostream</code>&nbsp;- 对非阻塞式的 socket 的简单封装,以方便常用读写操作</li>
<li><code>ioloop</code>&nbsp;- 核心的 I/O 循环</li>
</ul>
<p>&nbsp;</p>
<h1>tornado框架使用</h1>
<p>&nbsp;</p>
<p><strong>1、安装tornado</strong></p>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">pip install tornado
源码安装:https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz</pre>
</div>
<p><strong>2、先写一个入门级的代码吧,相信大家都能看懂,声明:tornado内部已经帮我们实现socket。</strong></p>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import tornado.ioloop

class 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()</pre>
</div>
<p>第一步:执行脚本,监听 8080 端口</p>
<p>第二步:浏览器客户端访问 /index &nbsp;--&gt; &nbsp;http://127.0.0.1:8080/index</p>
<p>第三步:服务器接受请求,并交由对应的类处理该请求</p>
<p>第四步:类接受到请求之后,根据请求方式(post / get / delete ...)的不同调用并执行相应的方法</p>
<p>第五步:然后将类的方法返回给浏览器</p>
<p>&nbsp;</p>
<h1>tornado路由系统</h1>
<p>&nbsp;</p>
<p>在tornado web框架中,路由表中的任意一项是一个元组,每个元组包含pattern(模式)和handler(处理器)。当httpserver接收到一个http请求,server从接收到的请求中解析出url path(http协议start line中),然后顺序遍历路由表,如果发现url path可以匹配某个pattern,则将此http request交给web应用中对应的handler去处理。</p>
<p>由于有了url路由机制,web应用开发者不必和复杂的http server层代码打交道,只需要写好web应用层的逻辑(handler)即可。Tornado中每个url对应的是一个类。</p>
<div class="cnblogs_Highlighter">
<pre class="brush:python;gutter:true;">#!/usr/bin/env python
# -*- coding:utf-8 -*-
__auth__ = "zhangyanlin"

import tornado.web
import tornado.ioloop

class 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("&lt;input type = 'text'&gt;")

class RegisterHandler(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
      self.write("&lt;input type = 'password'&gt;")

application = tornado.web.Application([
    (r'/index/(?P&lt;page&gt;\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()
</pre>
</div>
<p>观察所有的网页的内容,下面都有分页,当点击下一页后面的数字也就跟着变了,这种就可以用基础正则路由来做,下面我来给大家下一个网页分页的案例吧</p>
<div class="cnblogs_code"><img id="code_img_closed_6d360a1f-1199-4d63-87e1-df4a79b4e982" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_6d360a1f-1199-4d63-87e1-df4a79b4e982" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_6d360a1f-1199-4d63-87e1-df4a79b4e982" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
<span style="color: rgba(128, 0, 128, 1)">__auth__</span> = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zhangyanlin</span><span style="color: rgba(128, 0, 0, 1)">"</span>

<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop

LIST_INFO </span>=<span style="color: rgba(0, 0, 0, 1)"> [
    {</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">username</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">zhangyanlin</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">email</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">133@164.com</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">}
]
</span><span style="color: rgba(0, 0, 255, 1)">for</span> i <span style="color: rgba(0, 0, 255, 1)">in</span> range(200<span style="color: rgba(0, 0, 0, 1)">):
    temp </span>= {<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">username</span><span style="color: rgba(128, 0, 0, 1)">'</span>:str(i)+<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zhang</span><span style="color: rgba(128, 0, 0, 1)">"</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">email</span><span style="color: rgba(128, 0, 0, 1)">'</span>:str(i)+<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">@163.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">}
    LIST_INFO.append(temp)


</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Pagenation:

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span>(self,current_page,all_item,base_url):<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">当前页 内容总数 目录</span>
      <span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)">:
            page </span>=<span style="color: rgba(0, 0, 0, 1)"> int(current_page)
      </span><span style="color: rgba(0, 0, 255, 1)">except</span><span style="color: rgba(0, 0, 0, 1)">:
            page </span>= 1
      <span style="color: rgba(0, 0, 255, 1)">if</span> page &lt; 1<span style="color: rgba(0, 0, 0, 1)">:
            page </span>= 1<span style="color: rgba(0, 0, 0, 1)">

      all_page,c </span>= divmod(all_item,5<span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> c &gt;<span style="color: rgba(0, 0, 0, 1)"> 0:
            all_page </span>+=1<span style="color: rgba(0, 0, 0, 1)">

      self.current_page </span>=<span style="color: rgba(0, 0, 0, 1)"> page
      self.all_page </span>=<span style="color: rgba(0, 0, 0, 1)"> all_page
      self.base_url </span>=<span style="color: rgba(0, 0, 0, 1)"> base_url

    @property
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> start(self):
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> (self.current_page - 1) * 5<span style="color: rgba(0, 0, 0, 1)">

    @property
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> end(self):
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> self.current_page * 5

    <span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> string_pager(self):
      list_page </span>=<span style="color: rgba(0, 0, 0, 1)"> []
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> self.all_page &lt; 11<span style="color: rgba(0, 0, 0, 1)">:
            s </span>= 1<span style="color: rgba(0, 0, 0, 1)">
            t </span>= self.all_page + 1
      <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> self.current_page &lt; 6<span style="color: rgba(0, 0, 0, 1)">:
                s </span>= 1<span style="color: rgba(0, 0, 0, 1)">
                t </span>= 12
            <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                </span><span style="color: rgba(0, 0, 255, 1)">if</span> (self.current_page + 5) &lt;<span style="color: rgba(0, 0, 0, 1)"> self.all_page:
                  s </span>= self.current_page-5<span style="color: rgba(0, 0, 0, 1)">
                  t </span>= self.current_page + 6
                <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                  s </span>= self.all_page - 11<span style="color: rgba(0, 0, 0, 1)">
                  t </span>= self.all_page +1<span style="color: rgba(0, 0, 0, 1)">

      first </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "/index/1"&gt;首页&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">
      list_page.append(first)
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 当前页</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> self.current_page == 1<span style="color: rgba(0, 0, 0, 1)">:
            prev </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "javascript:void(0):"&gt;上一页&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span>
      <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            prev </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "/index/%s"&gt;上一页&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span>%(self.current_page-1<span style="color: rgba(0, 0, 0, 1)">,)
      list_page.append(prev)

      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">页码</span>
      <span style="color: rgba(0, 0, 255, 1)">for</span> p <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> range(s,t):
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> p==<span style="color: rgba(0, 0, 0, 1)"> self.current_page:
                temp </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a class = "active" href = "/index/%s"&gt;%s&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span>%<span style="color: rgba(0, 0, 0, 1)">(p,p)
            </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                temp </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "/index/%s"&gt;%s&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span> %<span style="color: rgba(0, 0, 0, 1)"> (p, p)
            list_page.append(temp)



      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 尾页</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> self.current_page ==<span style="color: rgba(0, 0, 0, 1)"> self.all_page:
            nex </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "javascript:void(0):"&gt;下一页&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span>
      <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            nex </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "/index/%s"&gt;下一页&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span> % (self.current_page + 1<span style="color: rgba(0, 0, 0, 1)">,)
      list_page.append(nex)

      last </span>= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">&lt;a href = "/index/%s"&gt;尾页&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'</span>%<span style="color: rgba(0, 0, 0, 1)">(self.all_page)
      list_page.append(last)


      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">跳转</span>
      jump = <span style="color: rgba(128, 0, 0, 1)">'''</span><span style="color: rgba(128, 0, 0, 1)">&lt;input type="text"&gt;&lt;a onclick = "Jump('%s',this);"&gt;GO&lt;/a&gt;</span><span style="color: rgba(128, 0, 0, 1)">'''</span>%(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index/</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      script </span>= <span style="color: rgba(128, 0, 0, 1)">'''</span><span style="color: rgba(128, 0, 0, 1)">
            &lt;script&gt;
                function Jump(baseUrl,ths){
                  var val = ths.previousElementSibling.value;
                  if (val.trim().length &gt; 0){
                        location.href = baseUrl + val;
                  }
                }
            &lt;/script&gt;
      </span><span style="color: rgba(128, 0, 0, 1)">'''</span><span style="color: rgba(0, 0, 0, 1)">
      list_page.append(jump)
      list_page.append(script)
      str_page </span>= <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">.join(list_page)

      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> str_page

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> IndexHandler(tornado.web.RequestHandler):

    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> get(self, page):
      obj </span>= Pagenation(page,len(LIST_INFO),<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index/</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      current_list </span>=<span style="color: rgba(0, 0, 0, 1)"> LIST_INFO
      str_page </span>=<span style="color: rgba(0, 0, 0, 1)"> obj.string_pager()
      self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">index.html</span><span style="color: rgba(128, 0, 0, 1)">'</span>, list_info=current_list, current_page=obj.current_page, str_page=<span style="color: rgba(0, 0, 0, 1)">str_page)

application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index/(?P&lt;page&gt;\d*)</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,IndexHandler)

])


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8080<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<span class="cnblogs_code_collapse">tornado服务端demo</span></div>
<div class="cnblogs_code"><img id="code_img_closed_be5986cb-90ea-49ed-8579-1122b10c9b80" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_be5986cb-90ea-49ed-8579-1122b10c9b80" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_be5986cb-90ea-49ed-8579-1122b10c9b80" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">DOCTYPE html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html </span><span style="color: rgba(255, 0, 0, 1)">lang</span><span style="color: rgba(0, 0, 255, 1)">="en"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">meta </span><span style="color: rgba(255, 0, 0, 1)">charset</span><span style="color: rgba(0, 0, 255, 1)">="UTF-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Title<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">
      .pager a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            display</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> inline-block</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            padding</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> 5px 6px</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            margin</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> 10px 3px</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            border</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> 1px solid #2b669a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            text-decoration</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">none</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>

      <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">
      .pager a.active</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            background-color</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> #2b669a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            color</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> white</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
      <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">h3</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>显示数据<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">h3</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">table </span><span style="color: rgba(255, 0, 0, 1)">border</span><span style="color: rgba(0, 0, 255, 1)">="1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">thead</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>用户名<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>邮箱<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">thead</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">tbody</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
            {% for line in list_info %}
                </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                  <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">td</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>{{line['username']}}<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">td</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                  <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">td</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>{{line['email']}}<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">td</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
            {% end %}
      </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">tbody</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">table</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="pager"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
      {% raw str_page %}
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<span class="cnblogs_code_collapse">前端HTML文件</span></div>
<p>注:两个文件必须放在同一个文件夹下,中间前端代码中有用到XSS攻击和模板语言,这两个知识点下面会详细解释</p>
<p>&nbsp;</p>
<h1>tornado 模板引擎</h1>
<p>&nbsp;</p>
<p>Tornao中的模板语言和django中类似,模板引擎将模板文件载入内存,然后将数据嵌入其中,最终获取到一个完整的字符串,再将字符串返回给请求者。</p>
<p>Tornado 的模板支持“控制语句”和“表达语句”,控制语句是使用&nbsp;<code>{%</code>&nbsp;和&nbsp;<code>%}</code>&nbsp;包起来的 例如&nbsp;<code>{% if len(items) &gt; 2 %}</code>。表达语句是使用&nbsp;<code>{{</code>&nbsp;和&nbsp;<code>}}</code>&nbsp;包起来的,例如&nbsp;<code>{{ items }}</code>。</p>
<p>控制语句和对应的 Python 语句的格式基本完全相同。我们支持&nbsp;<code>if</code>、<code>for</code>、<code>while</code>&nbsp;和&nbsp;<code>try</code>,这些语句逻辑结束的位置需要用&nbsp;<code>{% end %}</code>&nbsp;做标记。还通过&nbsp;<code>extends</code>&nbsp;和&nbsp;<code>block</code>&nbsp;语句实现了模板继承。这些在&nbsp;<code>template</code>&nbsp;模块&nbsp;的代码文档中有着详细的描述。</p>
<p>注:在使用模板前需要在setting中设置模板路径:"template_path" : "views"</p>
<div class="cnblogs_code">
<pre>settings =<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">views</span><span style="color: rgba(128, 0, 0, 1)">'</span>,             <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">设置模板路径,设置完可以把HTML文件放置views文件夹中</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static</span><span style="color: rgba(128, 0, 0, 1)">'</span>,            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 设置静态模板路径,设置完可以把css,JS,Jquery等静态文件放置static文件夹中</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_url_prefix</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/sss/</span><span style="color: rgba(128, 0, 0, 1)">'</span>,      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">导入时候需要加上/sss/,例如&lt;script src="/sss/jquery-1.9.1.min.js"&gt;&lt;/script&gt;</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">cookie_secret</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">asdasd</span><span style="color: rgba(128, 0, 0, 1)">"</span>,         <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">cookie生成秘钥时候需提前生成随机字符串,需要在这里进行渲染</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">xsrf_cokkies</span><span style="color: rgba(128, 0, 0, 1)">'</span>:True,               <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">允许CSRF使用</span>
}</pre>
<pre>application = tornado.web.Application([<br>    (r'/index',IndexHandler),<br>],**settings)                           #需要在这里加载</pre>
</div>
<p>文件目录结构如下:</p>
<p><img src="https://images2015.cnblogs.com/blog/938876/201607/938876-20160726220538544-674431219.png" alt=""></p>
<p><span style="font-size: 14px"><strong>1、模板语言基本使用for循环,if..else使用,自定义UIMethod以UIModule</strong></span></p>
<div class="cnblogs_code"><img id="code_img_closed_b118b4c3-7525-4814-9e6e-010d88d8ec6b" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b118b4c3-7525-4814-9e6e-010d88d8ec6b" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b118b4c3-7525-4814-9e6e-010d88d8ec6b" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> uimodule as md
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> uimethod as mt

INPUT_LIST </span>=<span style="color: rgba(0, 0, 0, 1)"> []
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MainHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      name </span>= self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">xxx</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,None)
      </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> name:
            INPUT_LIST.append(name)
      self.render(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">index.html</span><span style="color: rgba(128, 0, 0, 1)">"</span>,npm = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">NPM88888</span><span style="color: rgba(128, 0, 0, 1)">"</span>,xxoo =<span style="color: rgba(0, 0, 0, 1)"> INPUT_LIST)

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> post(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      name </span>= self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">xxx</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      INPUT_LIST.append(name)
      self.render(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">index.html</span><span style="color: rgba(128, 0, 0, 1)">"</span>, npm = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">NPM88888</span><span style="color: rgba(128, 0, 0, 1)">"</span>, xxoo =<span style="color: rgba(0, 0, 0, 1)"> INPUT_LIST)
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> self.write("Hello, World!!!")</span>
<span style="color: rgba(0, 0, 0, 1)">
settings </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">tpl</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 模板路径的配置</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">statics</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 静态文件路径的配置</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ui_methods</span><span style="color: rgba(128, 0, 0, 1)">'</span>:mt,      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 自定义模板语言</span>
    <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">ui_modules</span><span style="color: rgba(128, 0, 0, 1)">'</span>:md,      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 自定义模板语言</span>
<span style="color: rgba(0, 0, 0, 1)">}

</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">路由映射,路由系统</span>
application =<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,MainHandler),
],</span>**<span style="color: rgba(0, 0, 0, 1)">settings)


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 运行socket</span>
    application.listen(8000<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<span class="cnblogs_code_collapse">start.py</span></div>
<div class="cnblogs_code"><img id="code_img_closed_2e91bfb9-89ff-4f31-a2b8-f5d805ddff09" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_2e91bfb9-89ff-4f31-a2b8-f5d805ddff09" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_2e91bfb9-89ff-4f31-a2b8-f5d805ddff09" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">from</span> tornado.web <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> UIModule
</span><span style="color: rgba(0, 0, 255, 1)">from</span> tornado <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> escape

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> custom(UIModule):

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> render(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">张岩林</span><span style="color: rgba(128, 0, 0, 1)">"</span></pre>
</div>
<span class="cnblogs_code_collapse">uimodule</span></div>
<div class="cnblogs_code"><img id="code_img_closed_fbdc2dc0-64f5-45de-9f5f-c56eff9edb36" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_fbdc2dc0-64f5-45de-9f5f-c56eff9edb36" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_fbdc2dc0-64f5-45de-9f5f-c56eff9edb36" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> func(self,arg):
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> arg.lower()</pre>
</div>
<span class="cnblogs_code_collapse">uimethod</span></div>
<div class="cnblogs_code"><img id="code_img_closed_155e3a16-0c9d-488f-9482-47b10524e4ff" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_155e3a16-0c9d-488f-9482-47b10524e4ff" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_155e3a16-0c9d-488f-9482-47b10524e4ff" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
&lt;head&gt;
    &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;title&gt;Title&lt;/title&gt;
    &lt;link type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/css</span><span style="color: rgba(128, 0, 0, 1)">"</span> rel=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">stylesheet</span><span style="color: rgba(128, 0, 0, 1)">"</span> href=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">static/commons.css</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;script src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">static/zhang.js</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/script&gt;
    &lt;h1&gt;Hello world&lt;/h1&gt;
    &lt;h1&gt;My name <span style="color: rgba(0, 0, 255, 1)">is</span> zhangyanlin&lt;/h1&gt;
    &lt;h1&gt;输入内容&lt;/h1&gt;
    &lt;form action=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span> method=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">post</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
      &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text</span><span style="color: rgba(128, 0, 0, 1)">"</span> name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">xxx</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
      &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">submit</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">提交</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;/form&gt;
    &lt;h1&gt;展示内容&lt;/h1&gt;
    &lt;h3&gt;{{ npm }}&lt;/h3&gt;
    &lt;h3&gt;{{ func(npm)}}&lt;/h3&gt;
    &lt;h3&gt;{% module custom() %}&lt;/h3&gt;
    &lt;ul&gt;<span style="color: rgba(0, 0, 0, 1)">
      {</span>% <span style="color: rgba(0, 0, 255, 1)">for</span> item <span style="color: rgba(0, 0, 255, 1)">in</span> xxoo %<span style="color: rgba(0, 0, 0, 1)">}
            {</span>% <span style="color: rgba(0, 0, 255, 1)">if</span> item == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zhangyanlin</span><span style="color: rgba(128, 0, 0, 1)">"</span> %<span style="color: rgba(0, 0, 0, 1)">}
                </span>&lt;li style=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">color: red</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;{{item}}&lt;/li&gt;<span style="color: rgba(0, 0, 0, 1)">
            {</span>% <span style="color: rgba(0, 0, 255, 1)">else</span> %<span style="color: rgba(0, 0, 0, 1)">}
                </span>&lt;li&gt;{{item}}&lt;/li&gt;<span style="color: rgba(0, 0, 0, 1)">
            {</span>% end %<span style="color: rgba(0, 0, 0, 1)">}
      {</span>% end %<span style="color: rgba(0, 0, 0, 1)">}
    </span>&lt;/ul&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">index.html</span></div>
<p><strong>2、母板继承</strong></p>
<p>(1)、相当于python的字符串格式化一样,先定义一个占位符</p>
<div class="cnblogs_code"><img id="code_img_closed_475bd83e-b596-4593-a65e-5f75f0020d55" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_475bd83e-b596-4593-a65e-5f75f0020d55" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_475bd83e-b596-4593-a65e-5f75f0020d55" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta http-equiv=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-Type</span><span style="color: rgba(128, 0, 0, 1)">"</span> content=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/html; charset=UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
    &lt;title&gt;帅哥&lt;/title&gt;
    &lt;link href=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{{static_url(</span><span style="color: rgba(128, 0, 0, 1)">"</span>css/common.css<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">)}}</span><span style="color: rgba(128, 0, 0, 1)">"</span> rel=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">stylesheet</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;<span style="color: rgba(0, 0, 0, 1)">
    {</span>% block CSS %}{% end %<span style="color: rgba(0, 0, 0, 1)">}
</span>&lt;/head&gt;
&lt;body&gt;

    &lt;div <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">pg-header</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;

    &lt;/div&gt;<span style="color: rgba(0, 0, 0, 1)">
   
    {</span>% block RenderBody %}{% end %<span style="color: rgba(0, 0, 0, 1)">}
   
    </span>&lt;script src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{{static_url(</span><span style="color: rgba(128, 0, 0, 1)">"</span>js/jquery-1.8.2.min.js<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">)}}</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/script&gt;<span style="color: rgba(0, 0, 0, 1)">
   
    {</span>% block JavaScript %}{% end %<span style="color: rgba(0, 0, 0, 1)">}
</span>&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">layout.html</span></div>
<p>(2)、再子板中相应的位置继承模板的格式</p>
<div class="cnblogs_code"><img id="code_img_closed_c61b2d9d-bda7-43b4-9c56-efa0634534a1" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_c61b2d9d-bda7-43b4-9c56-efa0634534a1" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_c61b2d9d-bda7-43b4-9c56-efa0634534a1" class="cnblogs_code_hide">
<pre>{% extends <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">layout.html</span><span style="color: rgba(128, 0, 0, 1)">'</span>%<span style="color: rgba(0, 0, 0, 1)">}
{</span>% block CSS %<span style="color: rgba(0, 0, 0, 1)">}
    </span>&lt;link href=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{{static_url(</span><span style="color: rgba(128, 0, 0, 1)">"</span>css/index.css<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">)}}</span><span style="color: rgba(128, 0, 0, 1)">"</span> rel=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">stylesheet</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;<span style="color: rgba(0, 0, 0, 1)">
{</span>% end %<span style="color: rgba(0, 0, 0, 1)">}

{</span>% block RenderBody %<span style="color: rgba(0, 0, 0, 1)">}
    </span>&lt;h1&gt;Index&lt;/h1&gt;

    &lt;ul&gt;<span style="color: rgba(0, 0, 0, 1)">
    {</span>%<span style="color: rgba(0, 0, 255, 1)">for</span> item <span style="color: rgba(0, 0, 255, 1)">in</span> li %<span style="color: rgba(0, 0, 0, 1)">}
      </span>&lt;li&gt;{{item}}&lt;/li&gt;<span style="color: rgba(0, 0, 0, 1)">
    {</span>% end %<span style="color: rgba(0, 0, 0, 1)">}
    </span>&lt;/ul&gt;<span style="color: rgba(0, 0, 0, 1)">

{</span>% end %<span style="color: rgba(0, 0, 0, 1)">}

{</span>% block JavaScript %<span style="color: rgba(0, 0, 0, 1)">}
   
{</span>% end %}</pre>
</div>
<span class="cnblogs_code_collapse">index.html</span></div>
<p><strong>3、导入内容</strong></p>
<div class="cnblogs_code"><img id="code_img_closed_b40a161b-d964-482f-9ff5-1b1cc22ec799" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_b40a161b-d964-482f-9ff5-1b1cc22ec799" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_b40a161b-d964-482f-9ff5-1b1cc22ec799" class="cnblogs_code_hide">
<pre>&lt;div&gt;
    &lt;ul&gt;
      &lt;li&gt;张岩林帅&lt;/li&gt;
      &lt;li&gt;张岩林很帅&lt;/li&gt;
      &lt;li&gt;张岩林很很帅&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;</pre>
</div>
<span class="cnblogs_code_collapse">content.html</span></div>
<div class="cnblogs_code"><img id="code_img_closed_565e96f4-a591-4ce8-8403-71c193ae423e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_565e96f4-a591-4ce8-8403-71c193ae423e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_565e96f4-a591-4ce8-8403-71c193ae423e" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta http-equiv=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Content-Type</span><span style="color: rgba(128, 0, 0, 1)">"</span> content=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/html; charset=UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
    &lt;title&gt;张岩林&lt;/title&gt;
    &lt;link href=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{{static_url(</span><span style="color: rgba(128, 0, 0, 1)">"</span>css/common.css<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">)}}</span><span style="color: rgba(128, 0, 0, 1)">"</span> rel=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">stylesheet</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;div <span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">pg-header</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;<span style="color: rgba(0, 0, 0, 1)">
      {</span>% include <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">header.html</span><span style="color: rgba(128, 0, 0, 1)">'</span> %<span style="color: rgba(0, 0, 0, 1)">}
    </span>&lt;/div&gt;
   
    &lt;script src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">{{static_url(</span><span style="color: rgba(128, 0, 0, 1)">"</span>js/jquery-1.8.2.min.js<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">)}}</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/script&gt;
   
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">index.html</span></div>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">在模板中默认提供了一些函数、字段、类以供模板使用:

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: </span><span style="color: rgba(0, 0, 255, 1)">for</span><span style="color: rgba(0, 0, 0, 1)"> handler.static_url 的別名
xsrf_form_html: handler.xsrf_form_html 的別名</span></pre>
</div>
<p>&nbsp;</p>
<p>当你制作一个实际应用时,你会需要用到 Tornado 模板的所有功能,尤其是 模板继承功能。所有这些功能都可以在<code>template</code>&nbsp;模块&nbsp;的代码文档中了解到。(其中一些功能是在&nbsp;<code>web</code>&nbsp;模块中实现的,例如&nbsp;<code>UIModules</code>)</p>
<p>&nbsp;</p>
<h1>tornado cookie</h1>
<p>&nbsp;</p>
<p>Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于RFC2109和2965都已废弃,最新取代的规范是RFC6265。(可以叫做浏览器缓存)</p>
<p><strong>1、cookie的基本操作</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
   
<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
   
   
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MainHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> get(self):
      </span><span style="color: rgba(0, 0, 255, 1)">print</span>(self.cookies)            <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取所有的cookie</span>
      self.set_cookie(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">k1</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">v1</span><span style="color: rgba(128, 0, 0, 1)">'</span>)       <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 设置cookie</span>
      <span style="color: rgba(0, 0, 255, 1)">print</span>(self.get_cookie(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">k1</span><span style="color: rgba(128, 0, 0, 1)">'</span>))   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取指定的cookie</span>
      self.write(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Hello, world</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
   
application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, MainHandler),
])
   
   
</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<p><strong>2、加密cookie(签名)</strong></p>
<p>Cookie 很容易被恶意的客户端伪造。加入你想在 cookie 中保存当前登陆用户的 id 之类的信息,你需要对 cookie 作签名以防止伪造。Tornado 通过 set_secure_cookie 和 get_secure_cookie 方法直接支持了这种功能。 要使用这些方法,你需要在创建应用时提供一个密钥,名字为 cookie_secret。 你可以把它作为一个关键词参数传入应用的设置中:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
   
<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
   
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MainHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> get(self):
         </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span> self.get_secure_cookie(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mycookie</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">):             # 获取带签名的cookie
             self.set_secure_cookie(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">mycookie</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">myvalue</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)      # 设置带签名的cookie
             self.write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Your cookie was not set yet!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
         </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
             self.write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Your cookie was set!</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, MainHandler),
])
   
</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<p>签名Cookie的本质是:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">写cookie过程:

    将值进行base64加密
    对除值以外的内容进行签名,哈希算法(无法逆向解析)
    拼接 签名 </span>+<span style="color: rgba(0, 0, 0, 1)"> 加密值

读cookie过程:

    读取 签名 </span>+<span style="color: rgba(0, 0, 0, 1)"> 加密值
    对签名进行验证
    base64解密,获取值内容
</span></pre>
</div>
<p>用cookie做简单的自定义用户验证,下面会写一个绝对牛逼的自定义session用户验证</p>
<div class="cnblogs_code"><img id="code_img_closed_8985f495-1412-4233-876f-67cf461af0cd" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_8985f495-1412-4233-876f-67cf461af0cd" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_8985f495-1412-4233-876f-67cf461af0cd" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>

<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> BaseHandler(tornado.web.RequestHandler):

    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> get_current_user(self):
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> self.get_secure_cookie(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">login_user</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MainHandler(BaseHandler):

    @tornado.web.authenticated
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> get(self):
      login_user </span>=<span style="color: rgba(0, 0, 0, 1)"> self.current_user
      self.write(login_user)

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> LoginHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> get(self):
      self.current_user()

      self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">login.html</span><span style="color: rgba(128, 0, 0, 1)">'</span>, **{<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">''</span><span style="color: rgba(0, 0, 0, 1)">})

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> post(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):

      username </span>= self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">name</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      password </span>= self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">pwd</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> username == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">张岩林</span><span style="color: rgba(128, 0, 0, 1)">'</span> <span style="color: rgba(0, 0, 255, 1)">and</span> password == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">123</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
            self.set_secure_cookie(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">login_user</span><span style="color: rgba(128, 0, 0, 1)">'</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">张岩林</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
            self.redirect(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">login.html</span><span style="color: rgba(128, 0, 0, 1)">'</span>, **{<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">status</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">用户名或密码错误</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">})

settings </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_url_prefix</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/static/</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">cookie_secret</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">zhangyanlinhaoshuai</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
}

application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, MainHandler),
    (r</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/login</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, LoginHandler),
], </span>**<span style="color: rgba(0, 0, 0, 1)">settings)


</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<span class="cnblogs_code_collapse">自定义验证登录</span></div>
<p><strong>3、JavaScript操作Cookie</strong></p>
<p>由于Cookie保存在浏览器端,所以在浏览器端也可以使用JavaScript来操作Cookie。</p>
<div class="cnblogs_code">
<pre>/*<span style="color: rgba(0, 0, 0, 1)">
设置cookie,指定秒数过期,
name表示传入的key,
value表示传入相对应的value值,
expires表示当前日期在加5秒过期
</span>*/<span style="color: rgba(0, 0, 0, 1)">

function setCookie(name,value,expires){
    var temp </span>=<span style="color: rgba(0, 0, 0, 1)"> [];
    var current_date </span>=<span style="color: rgba(0, 0, 0, 1)"> new Date();
    current_date.setSeconds(current_date.getSeconds() </span>+ 5<span style="color: rgba(0, 0, 0, 1)">);
    document.cookie </span>= name + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">= </span><span style="color: rgba(128, 0, 0, 1)">"</span>+ value +<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">;expires=</span><span style="color: rgba(128, 0, 0, 1)">"</span> +<span style="color: rgba(0, 0, 0, 1)"> current_date.toUTCString();
}</span></pre>
</div>
<p>注:jQuery中也有指定的插件 jQuery Cookie 专门用于操作cookie,猛击这里</p>
<p>&nbsp;4、自定义session</p>
<p>本来这想新开一个帖子,但是还是把代码贴在这吧,有用到session验证的时候直接复制拿走就好</p>
<div class="cnblogs_code"><img id="code_img_closed_a288860a-8944-4f4f-bad2-5511dafe8c61" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a288860a-8944-4f4f-bad2-5511dafe8c61" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a288860a-8944-4f4f-bad2-5511dafe8c61" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">#!/usr/bin/env python
# -*- coding:utf-8 -*-
import tornado.web
import tornado.ioloop

container = {}
class Session:
    def __init__(self, handler):
      self.handler = handler
      self.random_str = None

    def __genarate_random_str(self):
      import hashlib
      import time
      obj = hashlib.md5()
      obj.update(bytes(str(time.time()), encoding='utf-8'))
      random_str = obj.hexdigest()
      return random_str

    def __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 = {}
            else:
                # 客户端有随机字符串
                if random_str in container.keys():
                  pass
                else:
                  random_str = self.__genarate_random_str()
                  container = {}
            self.random_str = random_str # self.random_str = asdfasdfasdfasdf

      container = value
      self.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 None
      value = user_info_dict.get(key, None)
      return value


class BaseHandler(tornado.web.RequestHandler):
    def initialize(self):
      self.session = Session(self)</span></pre>
</div>
<span class="cnblogs_code_collapse">自定义session</span></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1>XSS攻击和CSRF请求伪造</h1>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong><span style="font-size: 16px">XSS</span></strong></p>
<p>跨站脚本攻击(Cross Site Scripting),为不和层叠样式表(Cascading Style Sheets,&nbsp;CSS)的缩写混淆,故将跨站脚本攻击缩写为XSS。恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的特殊目的。</p>
<p>tornado中已经为我们给屏蔽了XSS,但是当我们后端向前端写前端代码的时候传入浏览器是字符串,而不是形成代码格式。所以就需要一个反解,在传入模板语言中前面加一个raw,例如{{ raw zhangyanlin }},这样通俗的讲可能不太懂,写一段代码,可能就懂了</p>
<div class="cnblogs_code"><img id="code_img_closed_6bdea431-c2b5-44f4-8383-931dfc5844f3" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_6bdea431-c2b5-44f4-8383-931dfc5844f3" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_6bdea431-c2b5-44f4-8383-931dfc5844f3" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">class IndexHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
      jump = '''</span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">a </span><span style="color: rgba(255, 0, 0, 1)">onclick </span><span style="color: rgba(0, 0, 255, 1)">= "Jump('%s',this);"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>GO<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">a</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">'''%('/index/')
      script = '''
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
                <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> Jump(baseUrl,ths){
                  </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> val </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ths.previousElementSibling.value;
                  </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">if</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> (val.trim().length </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">&gt;</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">0</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">){
                        location.href </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> baseUrl </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> val;
                  }
                }
            </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
      '''
      self.render('index.html',jump=jump,script=script)#传入两个前端代码的字符串</span></pre>
</div>
<span class="cnblogs_code_collapse">start.py</span></div>
<div class="cnblogs_code"><img id="code_img_closed_dc26951b-f1a1-4ade-994e-685e13a88aa8" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_dc26951b-f1a1-4ade-994e-685e13a88aa8" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_dc26951b-f1a1-4ade-994e-685e13a88aa8" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">DOCTYPE html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html </span><span style="color: rgba(255, 0, 0, 1)">lang</span><span style="color: rgba(0, 0, 255, 1)">="en"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">meta </span><span style="color: rgba(255, 0, 0, 1)">charset</span><span style="color: rgba(0, 0, 255, 1)">="UTF-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Title<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">
      .pager a</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            display</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> inline-block</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            padding</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> 5px</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            margin</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> 3px</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            background-color</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> #00a2ca</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
      <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">
      .pager a.active</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            background-color</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> #0f0f0f</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            color</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> white</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
      <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="pager"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
      {% raw jump %}
      {% raw script%}
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>    </pre>
</div>
<span class="cnblogs_code_collapse">index.html</span></div>
<p><strong><span style="font-size: 16px">CSRF</span></strong></p>
<p>CSRF(Cross-site&nbsp;request&nbsp;forgery跨站请求伪造,也被称为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。<br>当前防范 XSRF 的一种通用的方法,是对每一个用户都记录一个无法预知的 cookie 数据,然后要求所有提交的请求中都必须带有这个 cookie 数据。如果此数据不匹配 ,那么这个请求就可能是被伪造的。</p>
<p>Tornado 有内建的 XSRF 的防范机制,要使用此机制,你需要在应用配置中加上 xsrf_cookies 设定:xsrf_cookies=True,再来写一段代码,来表示一下:</p>
<div class="cnblogs_code"><img id="code_img_closed_560c999d-f797-47a4-b7f8-e895d8bbdcbc" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_560c999d-f797-47a4-b7f8-e895d8bbdcbc" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_560c999d-f797-47a4-b7f8-e895d8bbdcbc" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.web
import tornado.ioloop

class 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()</span></pre>
</div>
<span class="cnblogs_code_collapse">start.py</span></div>
<div class="cnblogs_code"><img id="code_img_closed_9d56e9ce-6d68-4948-9e55-c88beabc232d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_9d56e9ce-6d68-4948-9e55-c88beabc232d" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_9d56e9ce-6d68-4948-9e55-c88beabc232d" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
&lt;head&gt;
    &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;title&gt;Title&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/csrf</span><span style="color: rgba(128, 0, 0, 1)">"</span> method=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">post</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;<span style="color: rgba(0, 0, 0, 1)">
      {</span>% raw xsrf_form_html() %<span style="color: rgba(0, 0, 0, 1)">}
      </span>&lt;p&gt;&lt;input name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">user</span><span style="color: rgba(128, 0, 0, 1)">"</span> type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text</span><span style="color: rgba(128, 0, 0, 1)">"</span> placeholder=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">用户</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;&lt;/p&gt;
      &lt;p&gt;&lt;input name=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">pwd</span><span style="color: rgba(128, 0, 0, 1)">'</span> type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text</span><span style="color: rgba(128, 0, 0, 1)">"</span> placeholder=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">密码</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;&lt;/p&gt;
      &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">submit</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Submit</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
      &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Ajax CSRF</span><span style="color: rgba(128, 0, 0, 1)">"</span> onclick=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">SubmitCsrf();</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
    &lt;/form&gt;
   
    &lt;script src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/statics/jquery-1.12.4.js</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/script&gt;
    &lt;script type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">text/javascript</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;<span style="color: rgba(0, 0, 0, 1)">

      function ChangeCode() {
            var code </span>= document.getElementById(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">imgCode</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
            code.src </span>+= <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">?</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
      }
      function getCookie(name) {
            var r </span>= document.cookie.match(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">\\b</span><span style="color: rgba(128, 0, 0, 1)">"</span> + name + <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">=([^;]*)\\b</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">);
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> r ? r : undefined;
      }

      function SubmitCsrf() {
            var nid </span>= getCookie(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">_xsrf</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">);
            $.post({
                url: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/csrf</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
                data: {</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">k1</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">v1</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">_xsrf</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: nid},
                success: function (callback) {
                  </span>//<span style="color: rgba(0, 0, 0, 1)"> Ajax请求发送成功有,自动执行
                  </span>// callback,服务器write的数据 callback=<span style="color: rgba(0, 0, 0, 1)">“csrf.post”
                  console.log(callback);
                }
            });
      }
    </span>&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">csrf.html</span></div>
<p>简单来说就是在form验证里面生成了一段类似于自己的身份证号一样,携带着他来访问网页</p>
<p>&nbsp;</p>
<h1>tornado上传文件</h1>
<p>&nbsp;</p>
<p>上传文件这块可以分为两大类,第一类是通过form表单验证进行上传,还有一类就是通过ajax上传,下面就来介绍一下这两类</p>
<p><strong>1、form表单上传文件</strong></p>
<div class="cnblogs_code"><img id="code_img_closed_888f7aad-2082-44b0-afd4-d23addd33c68" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_888f7aad-2082-44b0-afd4-d23addd33c68" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_888f7aad-2082-44b0-afd4-d23addd33c68" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>

<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> IndexHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">index.html</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> post(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      file_metas </span>= self.request.files[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">"</span>]   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取文件信息</span>
      <span style="color: rgba(0, 0, 255, 1)">for</span> meta <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> file_metas:                        
            file_name </span>= meta[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">'</span>]                <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获得他的文件名字</span>
            file_names = os.path.join(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,file_name)
            with open(file_names,</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">wb</span><span style="color: rgba(128, 0, 0, 1)">'</span>) as up:         <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 打开本地一个文件</span>
                up.write(meta[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(128, 0, 0, 1)">'</span>])                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> body就是文件内容,把他写到本地</span>
<span style="color: rgba(0, 0, 0, 1)">
settings </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">views</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_url_prefix</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/statics/</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
}

application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,IndexHandler)
],</span>**<span style="color: rgba(0, 0, 0, 1)">settings)

</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<span class="cnblogs_code_collapse">start.py</span></div>
<div class="cnblogs_code"><img id="code_img_closed_60b09ca1-fa82-41b0-b6cc-d6df63b4ed67" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_60b09ca1-fa82-41b0-b6cc-d6df63b4ed67" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_60b09ca1-fa82-41b0-b6cc-d6df63b4ed67" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
&lt;head&gt;
    &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;title&gt;上传文件&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span> method=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">post</span><span style="color: rgba(128, 0, 0, 1)">"</span> enctype=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">multipart/form-data</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
      &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">file</span><span style="color: rgba(128, 0, 0, 1)">"</span> name = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
      &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">submit</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">提交</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">index.html</span></div>
<p><strong>&nbsp;2、ajax上传文件</strong></p>
<div class="cnblogs_code"><img id="code_img_closed_de62503f-0056-4c3e-bcce-b3ac1897d55e" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_de62503f-0056-4c3e-bcce-b3ac1897d55e" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_de62503f-0056-4c3e-bcce-b3ac1897d55e" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">my_form</span><span style="color: rgba(128, 0, 0, 1)">"</span> name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">form</span><span style="color: rgba(128, 0, 0, 1)">"</span> action=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">"</span> method=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">POST</span><span style="color: rgba(128, 0, 0, 1)">"</span>enctype=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">multipart/form-data</span><span style="color: rgba(128, 0, 0, 1)">"</span> &gt;
      &lt;div id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">main</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
            &lt;input name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">"</span> id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">my_file</span><span style="color: rgba(128, 0, 0, 1)">"</span>type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">file</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
            &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(128, 0, 0, 1)">"</span> name=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">action</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Upload</span><span style="color: rgba(128, 0, 0, 1)">"</span> onclick=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">redirect()</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;
            &lt;iframe id=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my_iframe</span><span style="color: rgba(128, 0, 0, 1)">'</span> name=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my_iframe</span><span style="color: rgba(128, 0, 0, 1)">'</span> src=<span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 255, 1)">class</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">hide</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/iframe&gt;
      &lt;/div&gt;
    &lt;/form&gt;

    &lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
      function redirect(){
            document.getElementById(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my_iframe</span><span style="color: rgba(128, 0, 0, 1)">'</span>).onload =<span style="color: rgba(0, 0, 0, 1)"> Testt;
            document.getElementById(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my_form</span><span style="color: rgba(128, 0, 0, 1)">'</span>).target = <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my_iframe</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">;
            document.getElementById(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">my_form</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">).submit();

      }
      
      function Testt(ths){
            var t </span>= $(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#my_iframe</span><span style="color: rgba(128, 0, 0, 1)">"</span>).contents().find(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).text();
            console.log(t);
      }
    </span>&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">HTML iframe</span></div>
<div class="cnblogs_code"><img id="code_img_closed_1413d2d9-c835-4eb0-a8c0-55fd82db5b46" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_1413d2d9-c835-4eb0-a8c0-55fd82db5b46" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_1413d2d9-c835-4eb0-a8c0-55fd82db5b46" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">file</span><span style="color: rgba(128, 0, 0, 1)">"</span> id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
    &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(128, 0, 0, 1)">"</span> onclick=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UploadFile();</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">提交</span><span style="color: rgba(128, 0, 0, 1)">"</span>/&gt;

    &lt;script src=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/statics/jquery-1.12.4.js</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;&lt;/script&gt;
    &lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
      function UploadFile(){
            var fileObj </span>= $(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">#img</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).files;
            var form </span>=<span style="color: rgba(0, 0, 0, 1)"> new FormData();
            form.append(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, fileObj);

            $.ajax({
                type:</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">POST</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
                url: </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
                data: form,
                processData: false,</span>// tell jQuery <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> to process the data
                contentType: false,</span>// tell jQuery <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> to set contentType
                success: function(arg){
                  console.log(arg);
                }
            })
      }
    </span>&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">Jquery 上传</span></div>
<div class="cnblogs_code"><img id="code_img_closed_697b26cf-c482-4cd3-8682-69b20d682701" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_697b26cf-c482-4cd3-8682-69b20d682701" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_697b26cf-c482-4cd3-8682-69b20d682701" class="cnblogs_code_hide">
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head lang=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">en</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;meta charset=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UTF-8</span><span style="color: rgba(128, 0, 0, 1)">"</span>&gt;
    &lt;title&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">file</span><span style="color: rgba(128, 0, 0, 1)">"</span> id=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
    &lt;input type=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">button</span><span style="color: rgba(128, 0, 0, 1)">"</span> onclick=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">UploadFile();</span><span style="color: rgba(128, 0, 0, 1)">"</span> value=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">提交</span><span style="color: rgba(128, 0, 0, 1)">"</span> /&gt;
    &lt;script&gt;<span style="color: rgba(0, 0, 0, 1)">
      function UploadFile(){
            var fileObj </span>= document.getElementById(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">).files;

            var form </span>=<span style="color: rgba(0, 0, 0, 1)"> new FormData();
            form.append(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, fileObj);

            var xhr </span>=<span style="color: rgba(0, 0, 0, 1)"> new XMLHttpRequest();
            xhr.open(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">post</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">, true);
            xhr.send(form);
      }
    </span>&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
</div>
<span class="cnblogs_code_collapse">XML提交</span></div>
<div class="cnblogs_code"><img id="code_img_closed_dbd7faa4-034d-4985-a01b-c64170070304" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_dbd7faa4-034d-4985-a01b-c64170070304" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_dbd7faa4-034d-4985-a01b-c64170070304" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>

<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> os

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> IndexHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">index.html</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> post(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      file_metas </span>= self.request.files[<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">"</span>]   <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取文件信息</span>
      <span style="color: rgba(0, 0, 255, 1)">for</span> meta <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> file_metas:
            file_name </span>= meta[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">filename</span><span style="color: rgba(128, 0, 0, 1)">'</span>]                <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获得他的文件名字</span>
            file_names = os.path.join(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static</span><span style="color: rgba(128, 0, 0, 1)">'</span>,<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">img</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,file_name)
            with open(file_names,</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">wb</span><span style="color: rgba(128, 0, 0, 1)">'</span>) as up:         <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 打开本地一个文件</span>
                up.write(meta[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(128, 0, 0, 1)">'</span>])                  <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> body就是文件内容,把他写到本地</span>
<span style="color: rgba(0, 0, 0, 1)">
settings </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">views</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">static_url_prefix</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/statics/</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
}

application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/index</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,IndexHandler)
],</span>**<span style="color: rgba(0, 0, 0, 1)">settings)

</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<span class="cnblogs_code_collapse">start.py</span></div>
<p>注:下面所有的实例用相同的python代码都能实现,只需要改前端代码,python代码文件名为start.py</p>
<p>&nbsp;</p>
<h1>tornado 生成随机验证码</h1>
<p>&nbsp;</p>
<p>&nbsp;用python生成随机验证码需要借鉴一个插件,和一个io模块,实现起来也非常容易,当然也需要借鉴session来判断验证码是否错误,下面写一段用户登录验证带验证码的,再看下效果,插件必须和执行文件必须放在更目录下</p>
<div class="cnblogs_code"><img id="code_img_closed_295d6c25-006e-4f47-ad34-a106a0886765" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_295d6c25-006e-4f47-ad34-a106a0886765" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_295d6c25-006e-4f47-ad34-a106a0886765" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">!/usr/bin/env python</span><span style="color: rgba(0, 128, 0, 1)">
#</span><span style="color: rgba(0, 128, 0, 1)"> -*- coding:utf-8 -*-</span>
<span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.web
</span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> tornado.ioloop

container </span>=<span style="color: rgba(0, 0, 0, 1)"> {}
</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Session:
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">(self, handler):
      self.handler </span>=<span style="color: rgba(0, 0, 0, 1)"> handler
      self.random_str </span>=<span style="color: rgba(0, 0, 0, 1)"> None

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__genarate_random_str</span><span style="color: rgba(0, 0, 0, 1)">(self):
      </span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> hashlib
      </span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> time
      obj </span>=<span style="color: rgba(0, 0, 0, 1)"> hashlib.md5()
      obj.update(bytes(str(time.time()), encoding</span>=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">utf-8</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">))
      random_str </span>=<span style="color: rgba(0, 0, 0, 1)"> obj.hexdigest()
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> random_str

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__setitem__</span><span style="color: rgba(0, 0, 0, 1)">(self, key, value):
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 在container中加入随机字符串</span>
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 定义专属于自己的数据</span>
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 在客户端中写入随机字符串</span>
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 判断,请求的用户是否已有随机字符串</span>
      <span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> self.random_str:
            random_str </span>= self.handler.get_cookie(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__session__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> random_str:
                random_str </span>= self.<span style="color: rgba(128, 0, 128, 1)">__genarate_random_str</span><span style="color: rgba(0, 0, 0, 1)">()
                container </span>=<span style="color: rgba(0, 0, 0, 1)"> {}
            </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 客户端有随机字符串</span>
                <span style="color: rgba(0, 0, 255, 1)">if</span> random_str <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> container.keys():
                  </span><span style="color: rgba(0, 0, 255, 1)">pass</span>
                <span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
                  random_str </span>= self.<span style="color: rgba(128, 0, 128, 1)">__genarate_random_str</span><span style="color: rgba(0, 0, 0, 1)">()
                  container </span>=<span style="color: rgba(0, 0, 0, 1)"> {}
            self.random_str </span>= random_str <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> self.random_str = asdfasdfasdfasdf</span>
<span style="color: rgba(0, 0, 0, 1)">
      container </span>=<span style="color: rgba(0, 0, 0, 1)"> value
      self.handler.set_cookie(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__session__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, self.random_str)

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> <span style="color: rgba(128, 0, 128, 1)">__getitem__</span><span style="color: rgba(0, 0, 0, 1)">(self, key):
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 获取客户端的随机字符串</span>
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 从container中获取专属于我的数据</span>
      <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">专属信息【key】</span>
      random_str =self.handler.get_cookie(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">__session__</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> random_str:
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> None
      </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 客户端有随机字符串</span>
      user_info_dict =<span style="color: rgba(0, 0, 0, 1)"> container.get(random_str,None)
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(0, 0, 255, 1)">not</span><span style="color: rgba(0, 0, 0, 1)"> user_info_dict:
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> None
      value </span>=<span style="color: rgba(0, 0, 0, 1)"> user_info_dict.get(key, None)
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> value


</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> BaseHandler(tornado.web.RequestHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> initialize(self):
      self.session </span>=<span style="color: rgba(0, 0, 0, 1)"> Session(self)


</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> LoginHandler(BaseHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">login.html</span><span style="color: rgba(128, 0, 0, 1)">'</span> ,state = <span style="color: rgba(128, 0, 0, 1)">""</span><span style="color: rgba(0, 0, 0, 1)">)

    </span><span style="color: rgba(0, 0, 255, 1)">def</span> post(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      username </span>= self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">username</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      password </span>= self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">password</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      code </span>=self.get_argument(<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">code</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">)
      check_code </span>= self.session[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CheckCode</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">]
      </span><span style="color: rgba(0, 0, 255, 1)">if</span> username ==<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zhangyanlin</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">and</span> password == <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">123</span><span style="color: rgba(128, 0, 0, 1)">"</span> <span style="color: rgba(0, 0, 255, 1)">and</span> code.upper() ==<span style="color: rgba(0, 0, 0, 1)"> check_code.upper():
            self.write(</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">登录成功</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)">:
            self.render(</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">login.html</span><span style="color: rgba(128, 0, 0, 1)">'</span>,state = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">验证码错误</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)

</span><span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> CheckCodeHandler(BaseHandler):
    </span><span style="color: rgba(0, 0, 255, 1)">def</span> get(self, *args, **<span style="color: rgba(0, 0, 0, 1)">kwargs):
      </span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> io
      </span><span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> check_code
      mstream </span>=<span style="color: rgba(0, 0, 0, 1)"> io.BytesIO()
      img,code </span>=<span style="color: rgba(0, 0, 0, 1)"> check_code.create_validate_code()
      img.save(mstream,</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">GIF</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
      self.session[</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">CheckCode</span><span style="color: rgba(128, 0, 0, 1)">'</span>] =<span style="color: rgba(0, 0, 0, 1)">code
      self.write(mstream.getvalue())


settings </span>=<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">template_path</span><span style="color: rgba(128, 0, 0, 1)">'</span>:<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">views</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">cookie_secret</span><span style="color: rgba(128, 0, 0, 1)">'</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">asdasd</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
}

application </span>=<span style="color: rgba(0, 0, 0, 1)"> tornado.web.Application([
    (r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/login</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,LoginHandler),
    (r</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">/check_code</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,CheckCodeHandler)
],</span>**<span style="color: rgba(0, 0, 0, 1)">settings)

</span><span style="color: rgba(0, 0, 255, 1)">if</span> <span style="color: rgba(128, 0, 128, 1)">__name__</span> == <span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">__main__</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">:
    application.listen(</span>8888<span style="color: rgba(0, 0, 0, 1)">)
    tornado.ioloop.IOLoop.instance().start()</span></pre>
</div>
<span class="cnblogs_code_collapse">start.py</span></div>
<div class="cnblogs_code"><img id="code_img_closed_93090525-6705-4e60-a268-cb2803a452fb" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_93090525-6705-4e60-a268-cb2803a452fb" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_93090525-6705-4e60-a268-cb2803a452fb" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;!</span><span style="color: rgba(255, 0, 255, 1)">DOCTYPE html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">html </span><span style="color: rgba(255, 0, 0, 1)">lang</span><span style="color: rgba(0, 0, 255, 1)">="en"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">meta </span><span style="color: rgba(255, 0, 0, 1)">charset</span><span style="color: rgba(0, 0, 255, 1)">="UTF-8"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>验证码<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">title</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">head</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">form </span><span style="color: rgba(255, 0, 0, 1)">action</span><span style="color: rgba(0, 0, 255, 1)">="/login"</span><span style="color: rgba(255, 0, 0, 1)"> method</span><span style="color: rgba(0, 0, 255, 1)">="post"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>用户名: <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> name</span><span style="color: rgba(0, 0, 255, 1)">="username"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span> <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>密码: <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="password"</span><span style="color: rgba(255, 0, 0, 1)"> name</span><span style="color: rgba(0, 0, 255, 1)">="password"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span> <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>验证码: <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text"</span><span style="color: rgba(255, 0, 0, 1)"> name</span><span style="color: rgba(0, 0, 255, 1)">="code"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">img </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="/check_code"</span><span style="color: rgba(255, 0, 0, 1)"> onclick</span><span style="color: rgba(0, 0, 255, 1)">="ChangeCode();"</span><span style="color: rgba(255, 0, 0, 1)"> id </span><span style="color: rgba(0, 0, 255, 1)">= "checkcode"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">p</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
      <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">input </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="submit"</span><span style="color: rgba(255, 0, 0, 1)"> value</span><span style="color: rgba(0, 0, 255, 1)">="submit"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span> <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>{{state}}<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">form</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">//</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 128, 0, 1)">当点击图片的时候,会刷新图片,这一段代码就可以实现</span>
    <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">function</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> ChangeCode() {
      </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">var</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> code </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.getElementById(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">checkcode</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
      code.src </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">+=</span> <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">?</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">"</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;
    }
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">body</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">html</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<span class="cnblogs_code_collapse">login.html</span></div>
<p>效果图如下:</p>
<p><img src="https://images2015.cnblogs.com/blog/938876/201607/938876-20160727151300888-1637202765.png" alt=""></p>
<p>插件下载地址:猛击这里</p>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/aylin/p/5702994.html
頁: [1]
查看完整版本: 浅析tornado web框架