目录

一、模板渲染

二、模板语法

2.1、变量输出

2.2、表达式输出

2.3、注释一个部分,防止他被输出

2.4、模板替换

2.5、模板继承

2.6、for循环

2.7、from引入包

2.8、import引入包

2.9、if分支

2.10、引入模板文件

2.11、渲染UI模块

2.12、不转义输出

2.13、设置局部变量

2.14、异常处理

2.15、while语句

2.16、static_url()函数

2.17、escape()函数

三、自定义函数

四、转义

五、CRSF/XSRF

5.1、使用模板

5.2、不使用模板


一、模板渲染

在handler中使用render()方法来渲染模板并返回给客户端。

import tornado.web
import tornado.ioloop
import tornado.httpserver
import osfrom tornado.options import define, optionsdefine("port", default=8000, help="run on the given port", type=int)class IndexHandler(tornado.web.RequestHandler):def get(self):self.render("index.html",price1=100,price2=200)current_path = os.path.dirname(__file__)
handlers = [(r"/",IndexHandler),
]if __name__ == "__main__":tornado.options.parse_command_line()app = tornado.web.Application(handlers,static_path = os.path.join(current_path,"static"),template_path = os.path.join(current_path, "template"),debug=True)http_server = tornado.httpserver.HTTPServer(app)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()

二、模板语法

2.1、变量输出

{{ ... }}

可以直接输出render时传过来的变量

2.2、表达式输出

输出python表达式,通过AutoEscape设置插入和输出{% %}.

2.3、注释一个部分,防止他被输出

{# ... #}.

这些标签可以被转义为{{!, {%!, and {#!
如果需要包含文字{{, {%, or {# 在输出中使用

2.4、模板替换

{% block *name* %}...{% end %}
指定一个可被替换的块 {% extends %}.

父块的块可以被字块所替换,例如::

 <!-- base.html --><title>{% block title %}Default title{% end %}</title><!-- mypage.html -->
{% extends "base.html" %}
{% block title %}My page title{% end %}

2.5、模板继承

{% extends *filename* %}

从另一个模板那里继承过来. extends包含一个或多个标签以从父模块那继承过来 ,不包含在块中的子模板及时存在标签页也会被忽略 , 详见 {% block %} 标签

2.6、for循环

{% for house in houses %}...{% end %}

这和 python 的for 是一样的。 {% break %} 和{% continue %} 语句是可以用于循环体之中的。

2.7、from引入包

{% from ... import ... %}

这和python的from、import语法是一样的。

2.8、import引入包

{% import ... %}

和python代码一样的声明 import

2.9、if分支

{% if ... %}...{% elif ... %}...{% else %}...{% end %}

表达式为真时,第一个条件语句会被输出 (在 elif 和 else之间都是可选的)

2.10、引入模板文件

{% include ... %}

包含另一个模板文件,所包含的模板文件可以使用所有的局部变量,如果是直接被 include进来的话(其中 {% autoescape %} 是个例外).另外, {% module Template(filename, **kwargs) %} 可以将两个模板的命名空间隔离.

2.11、渲染UI模块

{% module ... %}

示例:

我们页面上弹出一个小的弹窗

class Advertisement(UIModule):def render(self, *args, **kwargs):return self.render_string('alert_add.html')def css_files(self):return "/static/css/King_Chance_Layer7.css"def javascript_files(self):return ["/static/js/jquery_1_7.js","/static/js/King_Chance_Layer.js","/static/js/King_layer_test.js"]

增加alert_add.html

<div class="King_Chance_Layer"><div class="King_Chance_LayerCont" style="display:none;"><div class="King_Chance_Layer_Close">Close</div><div class="King_Chance_Layer_Title">SHOPBEST 商城SHOPBEST 商城SHOPBEST 商城SHOPBEST 商城</div><div class="King_Chance_Layer_Btn"><ul><li><a href="#" title="百搭潮">百搭潮</a></li><li><a href="#" title="抗皱棉">抗皱棉</a></li><li><a href="#" title="植绒">植绒</a></li><li><a href="#" title="潮范">潮范</a></li></ul></div><div class="King_Chance_Layer_Content"><ul><li><a href="#" title="百搭潮"><img src="/static/images/King_imgs/ipush1.jpg" alt="百搭潮"></a></li><li><a href="#" title="抗皱棉"><img src="/static/images/King_imgs/ipush2.jpg" alt="抗皱棉"></a></li><li><a href="#" title="植绒"><img src="/static/images/King_imgs/ipush3.jpg" alt="植绒"></a></li><li><a href="#" title="潮范"><img src="/static/images/King_imgs/ipush4.jpg" alt="潮范"></a></li></ul></div></div></div>
</div>

最后只需要在需要的页面添加如下代码就行

{% module Advertisement() %}

2.12、不转义输出

{% raw ... %}

输出的结果表达式没有autoescaping

2.13、设置局部变量

{% set 变量名=变量值 %}

2.14、异常处理

{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}

这和python try 相同.

2.15、while语句

{% while *condition* %}... {% end %}

和python的while一样。 {% break %} 和{% continue %} 可以在while循环中使用。

2.16、static_url()函数

Tornado模板模块提供了一个叫作static_url的函数来生成静态文件目录下文件的URL。如下面的示例代码:

<link href="{{ static_url('plugins/bootstrap/css/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ static_url('plugins/font-awesome/css/font-awesome.min.css') }}" rel="stylesheet">
<link href="{{ static_url('css/reset.css') }}" rel="stylesheet">
<link href="{{ static_url('css/main.css') }}" rel="stylesheet">
<link href="{{ static_url('css/index.css') }}" rel="stylesheet">

优点:

  • static_url函数创建了一个基于文件内容的hash值,并将其添加到URL末尾(查询字符串的参数v)。这个hash值确保浏览器总是加载一个文件的最新版而不是之前的缓存版本。无论是在你应用的开发阶段,还是在部署到生产环境使用时,都非常有用,因为你的用户不必再为了看到你的静态内容而清除浏览器缓存了。
  • 另一个好处是你可以改变你应用URL的结构,而不需要改变模板中的代码。例如,可以通过设置static_url_prefix来更改Tornado的默认静态路径前缀/static。如果使用static_url而不是硬编码的话,代码不需要改变。

2.17、escape()函数

关闭自动转义后,可以使用escape()函数来对特定变量进行转义,如:

{{ escape(text) }}

三、自定义函数

在模板中还可以使用一个自己编写的函数,只需要将函数名作为模板的参数传递即可,就像其他变量一样。代码如下:

Python:

import tornado.web
import tornado.ioloop
import tornado.httpserver
import osfrom tornado.options import define, optionsdefine("port", default=8000, help="run on the given port", type=int)# 自定义函数
def house_title_join(titles):return "+".join(titles)class IndexHandler(tornado.web.RequestHandler):def get(self):house_list = [{"price": 398,"titles": ["宽窄巷子", "160平大空间", "文化保护区双地铁"],"score": 5,"comments": 6,"position": "北京市丰台区六里桥地铁"},{"price": 398,"titles": ["宽窄巷子", "160平大空间", "文化保护区双地铁"],"score": 5,"comments": 6,"position": "北京市丰台区六里桥地铁"}]self.render("index.html", houses=house_list, title_join = house_title_join)current_path = os.path.dirname(__file__)
handlers = [(r"/",IndexHandler),
]if __name__ == "__main__":tornado.options.parse_command_line()app = tornado.web.Application(handlers,static_path = os.path.join(current_path,"static"),template_path = os.path.join(current_path, "template"),debug=True)http_server = tornado.httpserver.HTTPServer(app)http_server.listen(options.port)tornado.ioloop.IOLoop.instance().start()

HTML:

<ul class="house-list">{% if len(houses) > 0 %}{% for house in houses %}<li class="house-item"><a href=""><img src="/static/images/home01.jpg"></a><div class="house-desc"><div class="landlord-pic"><img src="/static/images/landlord01.jpg"></div><div class="house-price">¥<span>{{house["price"]}}</span>/晚</div><div class="house-intro"><span class="house-title">{{title_join(house["titles"])}}</span><em>整套出租 - {{house["score"]}}分/{{house["comments"]}}点评 - {{house["position"]}}</em></div></div></li>{% end %}{% else %}对不起,暂时没有房源。{% end %}</ul>

四、转义

我们新建一个表单页面new.html

<!DOCTYPE html>
<html><head><title>新建房源</title></head><body><form method="post"><textarea name="text"></textarea><input type="submit" value="提交"></form>{{text}}</body>
</html>

对应的handler为:

class NewHandler(RequestHandler):def get(self):self.render("new.html", text="")def post(self):text = self.get_argument("text", "") print textself.render("new.html", text=text)

当我们在表单中填入如下内容时:

<script>alert("hello!");</script>

此时写入的js程序并没有运行,而是显示出来了,这是因为tornado中默认开启了模板自动转义功能,防止网站受到恶意攻击。我们可以通过raw语句来输出不被转义的原始格式,如:

{% raw text %}

注意:在Firefox浏览器中会直接弹出alert窗口,而在Chrome浏览器中,需要set_header("X-XSS-Protection", 0)

若要关闭自动转义,一种方法是在Application构造函数中传递autoescape=None,另一种方法是在每页模板中修改自动转义行为,添加如下语句:

{% autoescape None %}

如果关闭自动转义后,我们可以使用escape()函数来对特定变量进行转义,如:

{{ escape(text) }}

五、CRSF/XSRF

CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。tornado 同样支持CSRF,和django类似,只需要在settings中开启csrf

settings = {"xsrf_cookies": True,
}
application = tornado.web.Application([(r"/", MainHandler),(r"/login", LoginHandler),
], **settings)

5.1、使用模板

前端:

<form action="/new_message" method="post">{{ module xsrf_form_html() }}        //在这里会自动生成xsrf的密钥<input type="text" name="message"/><input type="submit" value="Post"/>
</form>

后端:

class IndexHandler(RequestHandler):def get(self):self.render("index.html")def post(self):self.write("hello world")

模板中添加的语句帮我们做了两件事:

  • 为浏览器设置了_xsrf的Cookie(注意此Cookie浏览器关闭时就会失效)
  • 为模板的表单中添加了一个隐藏的输入名为_xsrf,其值为_xsrf的Cookie值

渲染后页面的源码:

<form method="post"><input type="hidden" name="_xsrf" value="2|543c2206|a056ff9e49df23eaffde0a694cde2b02|1476443353"/><input type="text" name="message"/><input type="submit" value="Post"/>
</form>

5.2、不使用模板

对于不使用模板的应用来说,首先要设置_xsrf的Cookie值,可以在任意的Handler中通过获取self.xsrf_token的值来生成_xsrf并设置Cookie。下面两种方式都可以起到设置_xsrf Cookie的作用。

class XSRFTokenHandler(RequestHandler):"""专门用来设置_xsrf Cookie的接口"""def get(self):self.xsrf_tokenself.write("Ok")class StaticFileHandler(tornado.web.StaticFileHandler):"""重写StaticFileHandler,构造时触发设置_xsrf Cookie"""def __init__(self, *args, **kwargs):super(StaticFileHandler, self).__init__(*args, **kwargs)self.xsrf_token

对于请求携带_xsrf参数,有两种方式:

  • 若请求体是表单编码格式的,可以在请求体中添加_xsrf参数
  • 若请求体是其他格式的(如json或xml等),可以通过设置HTTP头X-XSRFToken来传递_xsrf值

(1)请求体携带_xsrf参数

function getCookie(name) {var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");return r ? r[1] : undefined;
}function xsrfPost() {var xsrf = getCookie("_xsrf");$.post("/new", "_xsrf="+xsrf+"&key1=value1", function(data) {alert("OK");});
}

(2)请求体携带_xsrf参数

function getCookie(name) {var r = document.cookie.match("\\b" + name + "=([^;]*)\\b");return r ? r[1] : undefined;
}//AJAX发送post请求,json格式数据
function xsrfPost() {var xsrf = getCookie("_xsrf");var data = {key1:1,key1:2};
var json_data = JSON.stringify(data);$.ajax({url: "/new",method: "POST",headers: {"X-XSRFToken":xsrf,},data:json_data,success:function(data) {alert("OK");}})
}

Python3 --- Tornado之模板相关推荐

  1. Tornado之模板

    知识点 静态文件配置 static_path StaticFileHandler 模板使用 变量与表达式 控制语句 函数 块 4.1 静态文件 现在有一个预先写好的静态页面文件 (下载静态文件资源), ...

  2. 11 Tornado - 使用模板

    1. 路径与渲染 使用模板,需要仿照静态文件路径设置一样,向web.Application类的构造函数传递一个名为template_path的参数来告诉Tornado从文件系统的一个特定位置提供模板文 ...

  3. Python3 --- Tornado简介

    一.Tornado简介 Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中 ...

  4. web框架详解之 tornado 四 模板引擎、session、验证码、xss

    一.模板引擎 基本使用继承,extends 页面整体布局用继承导入,include 如果是小组件等重复的那么就用导入 下面是目录 首先在controllers里面创建一个文件,文件里面是页面类 #/u ...

  5. tornado模板引擎原理

    前言 老师问小明:已经a=1, 求a+1的值. 小明挠挠头,思考后回答:老师,a+1的结果是2. 以上是一个非常简单的例子,实际上就是一个模板编译过程. a=1,表示一个命名空间(namespace) ...

  6. t4 tornado 模板

    4.1 静态文件 现在有一个预先写好的静态页面文件 (下载静态文件资源), 我们来看下如何用tornado提供静态文件. static_path 我们可以通过向web.Application类的构造函 ...

  7. Python学习笔记——Tornado模板

    4.1 静态文件 现在有一个预先写好的静态页面文件 (下载静态文件资源), 我们来看下如何用tornado提供静态文件. static_path 我们可以通过向web.Application类的构造函 ...

  8. 3.(基础)tornado的接口调用顺序与模板

    上一节介绍了tornado的请求与响应,这一节介绍tornado的接口调用顺序和模板 首先都有哪些接口呢?作用是什么呢?并且都有的时候,执行顺序是怎么样的呢? 接口 1.initialize,表示初始 ...

  9. 模板数据tornado开发学习之2.输入输出,数据库操作,内置模板,综合示例

    最近用应开辟的过程中现出了一个小题问,趁便记载一下原因和方法--模板数据 用应python境环中的tornado行进web开辟上篇已决解了urlmap和基本行运机制的题问.接下来行进web程编就是一下 ...

最新文章

  1. 利用属性封装复杂的选项
  2. stm32之USART学习
  3. 调用非.net系统的Webservice的探索 ( 三 ) -WCF
  4. Web服务器超时处理
  5. rfid2-micro2440,keil4裸机
  6. cygwin swoole_swoole入门--------基础概念
  7. Microsoft Office 不同电脑不同电脑登录用户的数据同步
  8. 企业微信消息推送脚本
  9. html如何修改title前的小图标
  10. Liunx教程超详细(完整)
  11. 剪刀石头布java流程图_青岛能源所基于“剪刀石头布”策略实现快速多轮基因编辑...
  12. 流程图 自定义函数_让客户信任感倍增?酷家乐推出“自定义清单”功能,为精准报价加码!...
  13. 软件工程使用的编程语言
  14. mysql 在当前时间上加几小时
  15. Android 10 SystemUI 如何添加4G信号和WiFi图标
  16. torch.logical_and()方法
  17. 数据挖掘之-简单属性之间的相似度和相异度
  18. ZZULI郑州轻工业大学21级新生赛正式赛
  19. 上海京东招聘 Java_【上海京东工资】java开发工程师待遇-看准网
  20. mysql排列组合实现_排列-组合的代码实现

热门文章

  1. NTP服务端和客户端的部署——Chrony
  2. A. chino with string(ac自动机+floyd矩阵快速幂)
  3. web项目 Eclipse 中 jsp 页面 没有代码提示
  4. appium原理及api
  5. Linux中的定时自动执行功能(at,crontab)
  6. Muti-bin的一些相关函数和设置
  7. 分享一个音乐API接口
  8. Excel教程:规范Excel表格设计,让工作效率提升百倍不止
  9. 腾讯成立微信事业群 张小龙称保持小团队心态
  10. 剖析Mozilla代码之七武器