在js中單、雙引號引發來的是字符串,若是咱們要在字符串中使用單、雙引號,須要反斜槓進行轉義html
let str='user\'s name'; // or let str=" user's name"; // or let str="she said:\"...\".";
若是在字符串中輸出反斜槓,仍然是用反斜槓轉義,即2個反斜槓輸出1個反斜槓git
html標籤中,屬性值一般用雙引號引發來,也可使用單引號或不用引號。github
<input name=user /> <input name="user" /> <input name='user' />
這3種寫法都正確,不過一般咱們是選擇用雙引號引發來。
若是咱們要在屬性值中使用單、雙綽號,咱們不能直接寫成下面這樣dom
<input name=user'name /> <input name="user"name" /> <input name='user'name' />
這些所有是錯誤的。咱們要像在js中對單、雙引號轉義同樣,對屬性中的單、雙引號轉義xss
在html中輸出預留符號,可使用字符實體轉義的形式,這裏有簡單介紹:http://www.w3school.com.cn/html/html_entities.asp。即想輸出一個雙引號可使用"
的形式,工具
<input name="user"name" />
除此以外,html還支持十進制與十六進制編碼的形式輸出字符,如咱們知道字符a
的ascii
碼的十進制是97 十六進制是61
因此咱們在頁面body
中輸出一個字符a,有如下3種形式編碼
<body> a<!--直接輸出--> a<!--十進制輸出--> a<!--十六進制輸出--> </body>
一樣,單雙引號也有十進制(單:39,雙:34)與十六進制(單:27,雙:22),因此咱們在屬性中輸出一個單引號有2種選擇,十進制與十六進制code
<input name='user'name' /><!--十進制--> <input name='user'name' /><!--十六進制-->
而輸出一個雙引號則有3種選擇htm
<input name="user"name" /><!--實體--> <input name="user"name" /><!--十進制--> <input name="user"name" /><!--十六進制-->
咱們能夠經過dom節點提供的事件寫上調用js的代碼,如點擊body彈出hello這個字符串,咱們能夠寫成事件
<body onclick="alert('hello')"> click here </body>
若是咱們的需求是就彈出一個雙引號呢?
根據前述規則,咱們要寫成:
<body onclick="alert('"')"><!--這裏用十進制或十六進制均可以--> click here </body>
固然,alert裏的單引號也可使用十進制或十六進制編碼
<body onclick="alert("'")"><!--"單引號 '雙引號--> click here </body>
這樣也是能夠的。
是否是有點xss
的感受?
若是咱們把彈雙引號的需求改爲單引號呢?
<body onclick="alert(''')"><!--這樣html中是合法的,但js中並不合法,由於在js中,中間的單引號並無轉義--> click here </body>
若是咱們用十進制或十六進制編碼呢?
<body onclick="alert('"')"><!--這樣能夠嗎--> click here </body>
這樣仍然是不能夠的
咱們要對js字符串中的單引號進行轉義,如
<body onclick="alert('\'')"><!--轉義後可正確彈出--> click here </body>
或
<body onclick="alert('\"')"><!--轉義後可正確彈出--> click here </body>
前面的onclick="alert('\'')"
看起來還正常,後面的這個onclick="alert('\"')"
就有點不直觀了。由於後面這個看上去反斜槓像在轉義&
這1個字符,而&
在js的字符串中並不須要轉義的。
如前述的alert彈出的消息,若是是一個變量控制,動態輸出呢?
<body onclick="alert('${msg}')"> click here </body>
那咱們這個msg字符串就得注意了,從這個示例來看,這個動態的msg即出如今屬性onclick中,也出如今alert的單引號開始的字符串中。
咱們要對msg中的雙引號轉成"
或"
或"
,並對msg中單引號的前面加上一個反斜槓\
?
題外話:對msg中的反斜槓須要作double處理,由於反斜槓在html屬性中並非特殊的,但在js的字符串中是特殊的。所以正確的作法是對反斜槓及單引號前面各加上一個反斜槓
然而,你並不能保證屬性是用雙引號,alert中的字符串用的是單引號,由於能夠寫成下面這樣
<body onclick='alert("${msg}")'> click here </body>
?
這種狀況咱們要對msg中的單引號轉成'
或'
,並對msg中雙引號前面加上一個反斜槓\
題外話:同上
看上去要根據不一樣的狀況作不一樣的處理,其實也不須要
咱們只須要對單、雙引號前面加上一個反斜槓\
而後再對單、雙引號實體編碼便可。
在js中若是反斜槓後面跟的不須要反斜槓轉義的字符,那麼這個反斜槓是被丟棄的,所以像
var str="user\'s name";
單引號前面多加一個反斜槓也沒關係的。
在magix項目中,因爲magix-combine的支持,可識別出屬性中js代碼的部分,並自動化處理,如
<button mx-click="showName({name:'<%=name%>'})">click here</button>
name這個變量可包含任意的單、雙引號及反斜槓。工具自動識別並處理,開發者不須要作任何事情。
而對於這樣的寫法:
<button mx-click="showName({name:'"'})">click here</button> <!-- or--> <button mx-click="showName({name:'\"'})">click here</button>
第一種寫法其實並不正確,但第二種狀況看上去又怪怪的。magix-combine工具能識別出來是否須要添加反斜槓,並自動添加處理。
第一種須要添加反斜槓,工具會自動加上,並提醒開發者這裏的寫法是不正確的。
第二種說明開發者意識到了問題所在,本身處理了,工具就再也不處理也再也不提醒開發者。
相關連接:
https://github.com/thx/magix
https://github.com/thx/magix-combine