Tornado模板转义和模板继承


1.模板的转义

Tornado 默认会自动转义模板中的内容,把标签转换为相应的HTML实体。这样可以防止后端为数据库的网站被恶意脚本攻击。比如,

你的网站中有一个评论部分,用户可以在这里添加任何他们想说的文字进行讨论。虽然一些HTML标签在标记和样式冲突时不构成重大威胁

(如评论中没有闭标签),但标签会允许攻击者加载其他的JavaScript文件,打开通向跨站脚本攻击、XSS或漏洞之门。

首先看下面的例子

(r'/temp',TempHandler),

class TempHandler(tornado.web.RequestHandler):
    def get(self):
        username = self.get_argument('name','no')
        import time
        urllist = [
            ('https://www.kaiyuanzhognguo.com/','开源中国'),
            ('https://www.baidu.com/','百度'),
            ('https://www.zhihu.com/','知乎'),
        ]  
        self.render('escape.html',
                    username=username,
                    time=time,
                    urllist=urllist,
                    )

HTML文件如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{% if username!='no' %}
    欢迎用户 {{ username }} 登录
    <br>
    <img src="/static/images/c.jpg" width="250" height="250" >
    <br>

{% else %}
    您还没有登录
{% end %}
<br>
{% for url in urllist %}
    <a href="{{ url[0] }}" target="_blank" >{{ url[1] }}</a> <br>
{% end %}

</body>
</html>

这个地方在之前的基础上有添加了一点内容,可以在页面上引用我们的静态文件,这里我们引入了一个图片。

这个地方我们添加了链接,我们可以在页面上点击相应的页面来跳转到其他的页面去。

接下来我们在服务其中添加如下代码:

atag = "<a href='https://www.baidu.com/' target='_blank'>'---百度---' </a><br> "
self.render('03escape.html',
            username=username,
            time=time,
            urllist=urllist,
            atag=atag
            )

这个时候我们再来看看页面,我们发现这个时候我们加上的这个代码是作为一个字符串输出,并没有被浏览器解析出来,这个就是转义,tornado会自动的转义,把所有的输出都作为字符串,这样做的就能防止一些恶意代码在输出到前端时被执行,从而造成数据泄露。

当然这个默认自动是转义的,如果不要转义也是可以的,有如下方法:

#1.全局转义,在Application中添加配置项

autoescape=None,

#2.在文档最开始添加

{% autoescape None %} #实现整个文档转义

#在开启全局和文档不转义的情况下,可以使用 escape() 来开启变量的转义

{{ atag }}
{{ escape(atag) }}

#3.也可以使用 {% raw xxx %} 来输出不转义内容

{% raw atag %}

tornado是默认自动开启转义的,大家可以根据需求来选是否转义,但是要知道转义的本意是来防止浏览器意外执行恶意代码的,所以去掉转义的时候需要谨慎选择。

static_url函数来生成static目录下的URL

<!--html-->
<script src="{{ static_url(js/jquey-2.2.0.min.js) }}"></script>
<script src="/static/js/jquey-2.2.0.min.js"></script>

引用静态文件有上面 两种写法,使用上面的这种形式,那么为什么使用static_url而不是在你的模板中硬编码呢?有如下几个原因。其一,static_url函数创建了一个基于文件内容的hash值,并将其添加到URL末尾(查询字符串的参数v)。这个hash值确保浏览器总是加载一个文件的最新版而不是之前的缓存版本。无论是在你应用的开发阶段,还是在部署到生产环境使用时,都非常有用,因为你的用户不必再为了看到你的静态内容而清除浏览器缓存了。

2.模板的继承

把多个页面相同的内容提取出来放在一个base.html文件中,各个子html文件不同的内容 使用块语句占位,子html文件重写这个块中的内容。

base.html文件如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Tornado{%end%}</title>
    <link rel="shortcut icon" href="{{ static_url('images/favicon.ico') }}" type="image/x-icon" />
</head>
<body>
    {% block body%}
        this is base
    {% end %}
    {% block js %}{% end %}
</body>
</html>

extend.html如下

<!--继承的父模板-->
{% extends "base.html" %}

tornado 后台代码如下:

#路由映射如下
(r'/base',BaseIndexHandler),
(r'/extends',ExtendsHandler),

class BaseIndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('04base.html')

class ExtendsHandler(tornado.web.RequestHandler):
    def get(self):
        username = self.get_argument('name','no')
        self.render('05extends.html')

在上面,我们可以看到继承的模板里面没有写任何东西,只是继承了父模板,同样父模板的所有内容就都可以继承过来了,省去了大量的重复部分代码。

#从父模块继承
{% extends filename %}

#继承时子模板替换父模板中同名的块
{% block name %}
    #这里写的内容会替换模板中的内容,如果不写使用父模板的内容
{% end %}

#引入其他的模板文件

{% include filename %}

继承之后可以重写父类的块

<!--继承title块-->
{% block title %} {{ username }} {% end %}

<!--继承body块-->
{% block body %}
    {% if username!='no' %}
        欢迎用户 {{ username }} 登录
        <br>
        <img src="/static/images/c.jpg" width="250" height="250" >
        <br>
    {% else %}
        您还没有登录
    {% end %}
{% end %}

记住,当页面继承其他页面之后,需要实现相应的块才有作用,在块外面的代码是没有作用的。

当然可以引入模板,include.html如下:

在extends.html中添加如下:

hahahaha{% include "./include.html" %}

之后就可以看执行的效果

HTML文件

<!DOCTYPE html>
{% autoescape None %}<!--全局不转义-->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
welcome {{username}} 登录 <br>

{% if username != 'no' %}
    欢迎用户{{username}} 登录 <br>
{% else %}
    您还没有登录 <br>
{% end %}


<br>
{% for url in urllist %}
    <a href="{{url[0]}}" target="_blank">{{url[1]}}</a> <br>
{% end %}
{{atga}} <br>
{% raw atga %} <br> <!--局部不转义-->
{{ escape(atga) }} <!--局部转义-->

<script src="{{static_url('js/jquery-2.2.0.min.js')}}"></script>
<script src="/static/js/jquery-2.2.0.min.js"></script>
</body>
</html>

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM