在html中,有些字符是用于做特殊标记的,比如“<”。当需要在界面上显示这些字符时,就需要用另外一种方法来表示,比如“<”要表示为“<”。只要知道了html中各个符号替代字符串,写一个这样的函数算不上什么难事,可是有人却偏偏画蛇添足,并把添了足的代码放到了网上,结果使很多网站出错。
这段代码被放在一个名为《一些非常有用的Java常用方法》的帖子中。这个帖子被广泛转载,可以在很多技术网站找到它。不过因为很多网站自身可能也使用了帖子中的代码,所以这些网站都无法把这个帖子正确地表现出来。在我找了很久之后,终于找到了这帖子的本来面目。我现在把这帖子的原始内容贴出来,再把那些出错了的网站的中,该帖子的内贴出来,做个对比。希望CSDN没使用这个画蛇添足的htmlEncode,否则就对比出不来原始内容了。
原帖中的htmlEncode函数如下(代码1,Java语言,下同):
String htmlEncode(String txt)
{
txt = replace(txt,"&","& amp;");
txt = replace(txt,"& amp;amp;","& amp");
txt = replace(txt,"& amp;quot;","& quot;");
txt = replace(txt,"/"","& quot;");
txt = replace(txt,"& amp;lt;","& lt;");
txt = replace(txt,"<","& lt;");
txt = replace(txt,"& amp; gt;","& gt;");
txt = replace(txt,">","& gt;");
txt = replace(txt,"& amp;nbsp;","& nbsp");
txt = replace(txt," ","& nbsp");
return txt;
}
使用Google搜到的大多网站上的帖子中,该函数的内容如下(代码2):
String htmlEncode(String txt){ txt = replace(txt,"&","&"); txt = replace(txt,"& amp;","&"); txt = replace(txt,"& quot;","/""); txt = replace(txt,"/"","""); txt = replace(txt,"& lt;","<"); txt = replace(txt,"<","<"); txt = replace(txt,"& gt;",">"); txt = replace(txt,">",">"); txt = replace(txt,"& nbsp;"," "); txt = replace(txt," "," "); return txt; }
在这两段代码中replace是自定义的字符串内替换函数,这个我们先不管它。且看第二段代码中,有很多第2个参数和第3个参数相同的replace调用,不觉得很奇怪么?
在读过了很多这样奇怪代码的帖子之后,终于在一个网站上找到了正确的原始帖子,看到了这个htmlEncode函数的真面目,也就是代码1中的内容。
其实看代码1也有奇怪之处。按一般的想法,只要把“& < > / ”等这几个字符逐一替换成相应的替代字符串就可以了,怎么会有如txt = replace(txt,"&amp;","&");这样的语句呢?
后来一想,我明白了,作者是想让编码过的字符串不被重复编码。可能作者在程序的很多地方对字符串进行htmlEncode编码操作,他希望第一次编码后,其它的编码操作不再起作用,这样他只进行一次解码就可以还原原来的内容。
比如对字符串中的“&”,在进行第一次编码后,它将变为“&”。在第二次编码时,在对“&”进行替换后,将把“&”中的“&”再次换成“&”,于是得到“&amp;”。作者为了不重复编码,就在txt = replace(txt,"&","&");语句之后,又加了一句txt = replace(txt,"&amp;","&");把内容再替换回来。
同理,后面的txt = replace(txt,"&quot;",""");等类似语句也是为了达到这个目的加上去的。
作者写完这个程序之后一定很得意:看我这个程序多好,不会重复编码,调用100次htmlEncode也没关系,总能得到同一个结果!
可惜,这个结果并非总是正确的!试想,如果我想在网页上输出字符串"&",正如要显示作者的这个帖子所需要的那样,在内容中直接显示"&",问题来了:我对字符串"&"调用htmlEncode之后,得到的还是"&",我把"&"放到html中时,页面上只会显示一个”&”,而不是"&"。对于其它内容也一样,“<”、“≶”、“>”等这样的字符串都无法显示正确显示。
呵呵,这也正解释了为什么这么多网站会把作者的代码显示成代码2所示那样,因为他们都用了作者的程序。就拿作者帖子中的代码的第一句为例:
原文为:txt = replace(txt,"&","&");
使用作者的算法对这段内容进行htmlEncode,得到:
txt = replace(txt, "& ", "& ");
前一个“&”被替换为“&”,而第二个参数&不变。把这段代码放在html中送到浏览器,正好显示为:
txt = replace(txt,"&","&");
代码中其它的那些第2、3参数相同的replace调用也都是因为这个原因。
一句话,作者想优化html编码的功能,结果画蛇添足。
把代码改成如下的形式,去掉那些“足”,就可以正确编码了:
String htmlEncode(String txt) { txt = replace(txt,"&","& amp;"); txt = replace(txt,"/"","& quot;"); txt = replace(txt,"<","& lt;"); txt = replace(txt,">","& gt;"); txt = replace(txt," ","& nbsp;"); return txt; }
从编程的角度看,这只是个画蛇添足的问题。如果换个角度,还有一些有意思的事情:
一、很多网站都使用了这段代码,并因此而无法正确显示作者的帖子,可见网络上错误信息的危害,并提醒大家在使用网络上的代码时,一定加倍小心。
二、这段代码自己的错误导致了网站无法正确显示这段代码本身,这也限制了这段代码的使用。这算是网络自然法则么:正确的事物得以发展,不正确的自取灭亡?
希望CSDN没有使用这样的代码,否则我这个文章的内容也无法显示了。如果您转帖了本文,请千万检查一下,贴过去之后,内容还能正确显示否!
作者:苏林