在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