tokenization of html

2011-08-30 06:38

tokenization of html

by

at 2011-08-29 22:38:50

original http://yiminghe.iteye.com/blog/1160895

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> 

 

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

 

 

 

 

          <br><br>
          <span style="color:red">
            <a href="http://yiminghe.iteye.com/blog/1160895#comments" style="color:red">已有 <strong>2</strong> 人发表留言,猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br><br><br>

ITeye推荐