JSP中JSTL转义特殊字符失效:AJAX获取XML评论异常
嘿,我来帮你捋捋这个问题——核心问题出在XML响应的解析方式和内容格式不匹配,并不是JSTL的转义失效了,咱们一步步拆解:
为什么转义看似失效?
你虽然用了<c:out escapeXml="true">把评论里的XML特殊字符(<、>、&这些)转成了实体(<、>、&),但有两个关键环节出了问题:
Servlet没设置正确的Content-Type头
你的GetPostCommentsServlet转发到comments.jsp生成XML内容,但默认情况下,response的Content-Type是text/html,而不是application/xml。这就导致jQuery的$.get把返回的内容当作HTML字符串来解析,而不是XML对象。
当HTML解析器看到<这种XML实体时,会自动把它还原成原始的<字符。如果评论里有类似<script>或者未闭合的标签内容,还原后直接破坏了你原本的<ul>/<li>结构,浏览器的DOM解析器到这里就中断了,所以控制台会显示<ul></ul>的中断位置,内容自然加载不出来。XML文档的完整性可能不足
如果你的comments.jsp没有开头的XML声明(<?xml version="1.0" encoding="UTF-8"?>),或者里面的HTML标签写法不符合XML规范(比如某些自闭合标签没写/>,或者属性没加引号),也会让XML解析器(哪怕jQuery想解析成XML)报错,导致无法正确提取内容。
怎么解决?
按这几步来,问题就能搞定:
1. 在Servlet中设置正确的Content-Type
在doGet方法里,转发到comments.jsp之前,先加上这行代码:
response.setContentType("application/xml;charset=UTF-8");
这样服务器会明确告诉浏览器“我返回的是XML”,jQuery就会把响应解析成XML对象,而不是HTML,转义后的实体也不会被提前还原。
2. 确保comments.jsp生成合法的XML
给comments.jsp加上XML声明,并且保证里面的HTML标签符合XML规范(所有标签闭合,属性用引号包裹):
<?xml version="1.0" encoding="UTF-8"?> <cfeed> <ul> <c:forEach items="${post.comments}" var="example"> <li><c:out escapeXml="true" value="${example.comment}" /></li> </c:forEach> </ul> </cfeed>
这样生成的XML是完全合法的,XML解析器能正确识别<cfeed>、<ul>、<li>这些节点,评论里的转义实体也会被保留,直到你把内容插入页面时,浏览器才会把它们转换成对应的字符显示。
3. 前端回调的处理保持不变
你的AJAX回调代码没问题:
$.get("../GetPostComments", $.param(params), function(responseXml) { $("#example").prepend($(responseXml).find("cfeed").html()); });
当服务器返回正确的XML后,$(responseXml).find("cfeed").html()会准确提取出<cfeed>里的HTML内容,prepend到页面上时,转义后的内容会正常显示,不会破坏页面结构。
验证一下
做完上面的修改后,再测试带特殊字符的评论:比如评论内容是“我喜欢
内容的提问来源于stack exchange,提问作者Jonathan Laliberte

