tokenization of html

html 符号解析问题

 

场景:

 

在页面上输出包含已有数据的 textarea ,一般的做法即是,将所有的数据从数据库取出后都 escapeHtml 一下:

 

<textarea>&lt;script&gt;if(a&amp;&amp;1)alert(1);&lt;script&gt;</textarea>

 

页面瞬时增大了很多,特别是对于富文本情况(包含了很多 < > &) 等,但这又是必须做的,否则会被恶意结束 textarea 标签而造成 script 注入问题,但还是存在可以进一步减少体积的余地。

 

 

规范:

 

查看 html 对 textarea 标签及其内容的解析规则 :实际上textarea 的内容解析规则是按照 RCDATA 类型(一系列状态),简单描述如下

 

1. 遇到 & ,尽力得到实体字符 代表的值

2. 遇到 < , 如果下一个字符为 / 则结束当前标签

3. 否则作为 textarea 内容

 

恶意结束标签主要发生在 2 ,那么我们只要打破 2 ,保证 < 和 / 不相连即可,在服务器端渲染页面事先只做一点处理,再把处理后的内容放在 textarea 中:

 

"<a>x</>".replace(/<\//gi,"&lt;/")

 

而如果允许用户输入 &gt; 等代表实体字符的字符串,则还要进行 & 替换:

 

"<a>x</>".replace(/&/gi,"&amp;")

 

最终页面体积也能减小不少.

 

其他类型:

 

 tokenization 部分还存在其他特殊类型的解析规则,比如常见的 script ,在 xhtml 时代,推荐的写法是:

 

<script type="text/javascript">
/* <![CDATA[ */
// TODO
/* ]]> */
</script> 

 

这在 html 中也是支持的, cdata 的解析规则 比较简单:在遇到 ]]> 之前都算作 script 的内容,并不解析实体字符.

 

而 html 则是完全可以不用 cdata 这个规则的 ,script 解析本身就是一种单独规则了:

 

1. 类似 rcdata (因此代码中不能出现类似 "</script>",必须改做 "<\/script>"),但是不解析实体字符

2. 还识别了 <!-- ,似乎是为了兼容不支持js的远古浏览器的注释:

 

 

<script type="text/javascript">
<!-- // hide from really old browsers that noone uses anymore
// TODO
// -->
</script> 

 

这在现在看来则是完全不必要了。

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值