Python3 --- Tornado之模板
目录
一、模板渲染
二、模板语法
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之模板相关推荐
- Tornado之模板
知识点 静态文件配置 static_path StaticFileHandler 模板使用 变量与表达式 控制语句 函数 块 4.1 静态文件 现在有一个预先写好的静态页面文件 (下载静态文件资源), ...
- 11 Tornado - 使用模板
1. 路径与渲染 使用模板,需要仿照静态文件路径设置一样,向web.Application类的构造函数传递一个名为template_path的参数来告诉Tornado从文件系统的一个特定位置提供模板文 ...
- Python3 --- Tornado简介
一.Tornado简介 Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架,由FriendFeed公司在自己的网站FriendFeed中 ...
- web框架详解之 tornado 四 模板引擎、session、验证码、xss
一.模板引擎 基本使用继承,extends 页面整体布局用继承导入,include 如果是小组件等重复的那么就用导入 下面是目录 首先在controllers里面创建一个文件,文件里面是页面类 #/u ...
- tornado模板引擎原理
前言 老师问小明:已经a=1, 求a+1的值. 小明挠挠头,思考后回答:老师,a+1的结果是2. 以上是一个非常简单的例子,实际上就是一个模板编译过程. a=1,表示一个命名空间(namespace) ...
- t4 tornado 模板
4.1 静态文件 现在有一个预先写好的静态页面文件 (下载静态文件资源), 我们来看下如何用tornado提供静态文件. static_path 我们可以通过向web.Application类的构造函 ...
- Python学习笔记——Tornado模板
4.1 静态文件 现在有一个预先写好的静态页面文件 (下载静态文件资源), 我们来看下如何用tornado提供静态文件. static_path 我们可以通过向web.Application类的构造函 ...
- 3.(基础)tornado的接口调用顺序与模板
上一节介绍了tornado的请求与响应,这一节介绍tornado的接口调用顺序和模板 首先都有哪些接口呢?作用是什么呢?并且都有的时候,执行顺序是怎么样的呢? 接口 1.initialize,表示初始 ...
- 模板数据tornado开发学习之2.输入输出,数据库操作,内置模板,综合示例
最近用应开辟的过程中现出了一个小题问,趁便记载一下原因和方法--模板数据 用应python境环中的tornado行进web开辟上篇已决解了urlmap和基本行运机制的题问.接下来行进web程编就是一下 ...
最新文章
- 利用属性封装复杂的选项
- stm32之USART学习
- 调用非.net系统的Webservice的探索 ( 三 ) -WCF
- Web服务器超时处理
- rfid2-micro2440,keil4裸机
- cygwin swoole_swoole入门--------基础概念
- Microsoft Office 不同电脑不同电脑登录用户的数据同步
- 企业微信消息推送脚本
- html如何修改title前的小图标
- Liunx教程超详细(完整)
- 剪刀石头布java流程图_青岛能源所基于“剪刀石头布”策略实现快速多轮基因编辑...
- 流程图 自定义函数_让客户信任感倍增?酷家乐推出“自定义清单”功能,为精准报价加码!...
- 软件工程使用的编程语言
- mysql 在当前时间上加几小时
- Android 10 SystemUI 如何添加4G信号和WiFi图标
- torch.logical_and()方法
- 数据挖掘之-简单属性之间的相似度和相异度
- ZZULI郑州轻工业大学21级新生赛正式赛
- 上海京东招聘 Java_【上海京东工资】java开发工程师待遇-看准网
- mysql排列组合实现_排列-组合的代码实现