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