你还在用${ }取值吗?珍爱网都没注意的小细节
${}取值与 c:out标签取值的不同
我们通过一段代码来看一下效果,下面的代码中我们用$取出一个带有特殊符号的变量
输出结果如下
原因分析
从结果上可以看出EL表达式没能再表单中正常显示,可能很多读者已经反应过来了,因为我们设置的name值中的【 '> 】会导致input框提前结束。以至于表单的结构被打乱了。而 标签的取值却没有问题,我们打开浏览器源码查看一下
原来 标签转义了输出变量中会导致浏览器迷惑的字符,把这些有问题的字符转化为HTML字符实体码(character-entity code);这样就能避免用户在提交了一些有意无意为之的特殊字符时引起表单的错误。
看看那些人犯了这样的错误
这样的错误到底有没有人会犯呢?当然新人肯定有时候会不注意这个,我是说中小型网站。下面的图片是我在美食杰网站上发布菜谱时,在主料一栏中填入"> 保存后在打开的效果,当然美食杰是PHP做的但是关键不在语言,通过这个现象我们可以看到这样的错误是存在的。
如果这个网站大家觉得有点牵强的话,我还是找个用java写的网站来说吧。下图是珍爱网,我在名字中输入">后的结果,同样会引起表单提前结束,珍爱网应该是Java做的。
总结一下
其实使用c:out 标签不光是HTML转义的问题能够得到解决,这种字符转换还能预防跨站脚本攻击。
如果不转换的话我可以在文本框中输入
<script>window.location.href="xxx.xx.com"</script>
这样就会导致这个页面打开时直接连接到其他网站。而如果使用了<c:out>转义则可以很好的避免这个问题。当然使用<c:out>是不是能够解决所有的问题,我觉得有点悬,还是要根据情况来做对应的处理,但是使用总是比没使用好。
但是<c:out>在使用的时候要注意一个问题,不是所有的地方都可以直接使用的。比如说要显示html的地方,如果一篇文章的详情,或者一个商品的详细描述,这样本来就是富文本的内容不能直接使用<c:out>会导致内容无法查看, <c:out >标签有一个可选属性 escapeXml 这个属性默认是true启用转义,你可以设置为false关闭它。
<c:out>的替代方案
说了这么多如果你还是坚持使用${}来输出变量值的话也不是没有办法解决这个问题,可以使用fn函数中的escapeXml方法来转义字符,使用方式如下
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> <input value="${fn:escapeXml(name) }" >
到底使用<c:out>还是使用fn:escapeXml()函数来转化特殊字符,其实取决于你的个人喜好,我还是比较喜欢<c:out>标签,相对而言在使用上简单一点,也容易记住, 而且<c:out>标签还有一个功能,就是在取值为null的情况下能够指定默认值,这个是fn:escapeXml()函数所没有的,提供默认值在某些情况下回带来很多方便,这也是我选择<c:out>的一个原因。