Django模板中的關閉和開啓HTML自動轉義,解析

做Web開發的人都明白,我們應該避免在用戶輸入信息中出現HTML標籤。比如考慮下面的Django模板信息:

Hello {{ name }}.

這看起來沒什麼問題,但是假如用戶輸入的name是下面這樣的信息就麻煩了:

<script type="text/javascript">// <![CDATA[
alert(’hello’)
// ]]></script>

瀏覽器會解析這個信息並彈出一個對話框,這顯然不是我們所希望的。毫無疑問,對於用戶輸入的信息,我們總是應該進行驗證。你不知道是否會有一個“惡意”的用戶會利用這個漏洞來做一些不好的事情。
爲了避免以上問題,你有兩個選擇:

1. 給每個變量加上一個escape過濾器來進行HTML轉義。Django剛發佈那幾年都是這樣要求開發人員的。但是,這相當於把責任踢給了開發人員。難免會有人忘記了寫這個轉義過濾器。

2. 或者你可以選擇使用Django的自動HTML轉義功能,下面我將介紹它。

缺省情況下的轉義方式是這樣的:

•  < 被轉換爲 <
•  > 被轉換爲 >
• ’  (單引號)被轉換爲 '

 

• ” (雙引號)被轉換爲 "
• & 被轉換爲 &

 

上面的轉義規則是缺省的,所以如果你不想讓某段信息被執行HTML轉義,可以這樣:

1. 對於單個變量,可以在其後面加上safe過濾器,告訴Django這個字符串不用進行HTML轉義。比如:

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}

如果其中的data的值是 <b> 上面兩行的最終輸出結果爲:

This will be escaped: <b>
This will not be escaped: <b>


2. 對於一段模板內容可以使用autoescape標籤,比如:

{% autoescape off %}
Hello {{ name }}
{% endautoescape %}

這裏的off 參數表明被autoescape包含的信息都不需要執行HTML轉義。on 參數表示需要執行HTML轉義,比如有的時候你希望一段信息中大部分不需要HTML轉義,但是其中某個部分需要HTML轉義,可以這樣:

{% autoescape off %}
This will not be auto-escaped: {{ data }}.
Nor this: {{ other_data }}
{% autoescape on %}
Auto-escaping applies again: {{ name }}
{% endautoescape %}
{% endautoescape %}

另外需要注意的一點是autoescape是存在繼承性的,比如你在父模板中有一個autoescape標籤並且參數爲off,那麼繼承它的子模板也會在相應的部分繼承這一特性。比如:

# base.html
{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}

# child.html 
{% extends "base.html" %}
{% block title %}This & that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}


最後要提一下 字符串的default過濾器,比如下面這個例子:

{{ data|default:"This is a string literal." }}

如果你在default:後面的缺省值中包含了HTML特殊字符,那麼是不會被轉義的,比如你應該按照下面第一種的方式來寫,而不是第二種:

# 正確的寫法

{{ data|default:"3 < 2" }}

# 錯誤的寫法
{{ data|default:"3 < 2" }}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章