解决ajax程序访问服务器返回的XML文件时, firebug出现: XML 解析错误问题

在ajax中使用xml文本时, 出现xmlHttpRequest.responseText显示正确的数据, 并且服务器返回HTTP 200(OK), 但是使用firebug查看xml文件时,却出现如下错误:
“XML解析错误:废弃 document 元素之后的内容 位置:moz-nullprincipal{uuid} “(注意这里的uuid是com对象的标识符, 是一个128位的二进制数据.).
错误原因分析:
1>  xml文件格式错误
2>  未设置服务器返回文件的MIME类型.
在JSP中解决问题如下:
1>  保证在书写服务器响应的JSP文件的不能包含其他任何标签, 文本,即在该JSP文件中只能包含JSP源代码, 其他任何HTML标签, DOCTYPE声明等均不能有, 因为在服务器响应客户端返回数据时同样会返回那些标签, 所以才会Firebug才会出现XML文件解析错误.
2>  response.setContenttType(“text/xml; charset=UTF-8”);

注: 样例代码中的客户端代码来自于javascript学习指南(Oreilly出版社)这本书中, 并作部分修改; 服务器端代码是本人根据javascript学习指南(Oreilly出版社)这本书中的php代码改写的纯JSP代码, 小弟初学javascript, 仅供大家参考.


首先是客户端文件
:

<!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

  <head>

     <title>Ajax Hello World XML,并且处理禁用javascript的情形,服务器端返回xml格式数据</title>

     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>

     <style type="text/css">

       div.elem{

          margin:20px;

       }

       div#cities{

          display:none;

       }

     </style>

     <script type="text/javascript">

      //<![CDATA[

       

       varxmlHttpObj=null;

       

       functioncatchEvent(eventObj,eventTypeName, eventHandler){

          if(eventObj.addEventListener){

             eventObj.addEventListener(eventTypeName,eventHandler, false);

          }else if(eventObj.attachEvent){

             varevent ="on"+ eventTypeName;

             eventObj.attachEvent(event,eventHandler);

          }

       }

       

       catchEvent(window,"load",function(){

          document.getElementById("cities").style.display="block";

          //当在浏览器中禁用javascript, javascript代码就不会执行,

           //就会显示出来getCities按钮,进而通过表单提交来获取数据.

          document.getElementById("getCities").style.display="none";

          document.getElementById("provinceList").οnchange= populateList;

       });

       

       /*

       //创建XHR对象

       functiongetXmlHttp(){

          varxmlHttp = null;

          if(window.XMLHttpRequest){

             xmlHttp= new XMLHttpRequest();

             //设置响应数据为xml格式

             if(xmlHttp.overrideMimeType){

                xmlHttp.overrideMimeType('text/xml');

             }

          }elseif(window.ActiveXObject){

             //创建IE浏览器的XMLHttpRequest对象

             xmlHttp= new ActiveXObject("Microsoft.XMLHTTP");

          }

          returnxmlHttp;

       }

       */

       

        //更健壮的创建跨浏览器的XMLHttpRequest对象的代码

       function getXmlHttp(){

          varxmlHttp =null;

          if(window.XMLHttpRequest){

             xmlHttp= newXMLHttpRequest();

          }else{

             try{

                xmlHttp= newActiveXObject("Msxml2.XMLHTTP");

             }catch(e){

                try{

                   xmlHttp= newActiveXObject("Microsoft.XMLHTTP");

                }catch(e){

                   returnxmlHttp;

                }

             }

          }

          returnxmlHttp;

       }

 

       /*

       //使用GET方法准备并发送XHR请求

       functionpopulateList(){

          varprovince = document.getElementById("provinceList").value;

          varurl = "../jssource/xml_cities.jsp?province=" + province;

          

          //如果不支持xmlHttpObj

          if(!xmlHttpObj)xmlHttpObj = getXmlHttp();

          if(!xmlHttpObj)return;

          

          xmlHttpObj.open('GET',encodeURI(url), true);

          xmlHttpObj.onreadystatechange= getCities;

          xmlHttpObj.send(null);

       }

       */

       

        //使用POST方法准备并发送XHR请求

       function populateList(){

          varprovince =document.getElementById("provinceList").value;

          varurl ="../jssource/xml_cities.jsp";

          varquery ="province="+ province;

          

          if(!xmlHttpObj) xmlHttpObj= getXmlHttp();

          if(!xmlHttpObj)return;

          

          xmlHttpObj.open('POST', encodeURI(url),true);

          xmlHttpObj.onreadystatechange= getCities;

          xmlHttpObj.setRequestHeader("Content-type","application/x-www-form-urlencoded");

          xmlHttpObj.send(query);

       }

       //处理返回的数据

       function getCities(){

          if(xmlHttpObj.readyState== 4 && xmlHttpObj.status == 200){

             try{

                /*

                alert("xmlHttpObj.responseText="+ xmlHttpObj.responseText);

                alert(xmlHttpObj.responseXML);

                alert(xmlHttpObj.responseXML.documentElement);

                */

                

                 //获取显示城市信息的下拉列表框

                var citySelection = document.getElementById("citySelection");

                

                //在外部XML文件中也可以使用DOM方法

                var cityNodes = xmlHttpObj.responseXML.getElementsByTagName("city");

                //移除citySelection中的所有options节点数据,将其值为空.

                citySelection.innerHTML= "";

                

                //遍历每个city节点

                for(vari = 0, length =cityNodes.length; i < length; i++){

                   varname =null;

                   vartitle =null;

                   //或者var name =title = null;

                   varcity = cityNodes[i];      

                   for(varj = 0, nodesLength =city.childNodes.length; j < nodesLength; j++){

                     //elem1中的到的是XML标签

                      varelem1 = city.childNodes[j].nodeName;

                     //elem2是与elem1标签对应的数据

                      varelem2 = city.childNodes[j].firstChild.nodeValue;

                     if(elem1 =='name'){

                        name= elem2;

                     }else{

                        title= elem2;

                     }

                   }

                   //为下拉列表框添加一个新元素

                   citySelection.options[i]= newOption(name,title);

                }

             }catch(e){

                alert(e.message);

             }

             

          }else if(xmlHttpObj.readyState== 4 && xmlHttpObj.status != 200){

             document.getElementById("cities").innerHTML="Error:获取数据失败!";

          }

       }

     //]]>

      </script>

  </head>

  <body>

     <h3>选择省份</h3>

     当在浏览器中禁用javascript, javascript代码就不会执行,

     就会显示出来getCities按钮,进而通过表单提交来获取数据.

     <form action="/struts_learining/jssource/xml_cities.jsp"method="GET">

       <div class="elem">

          <select id="provinceList" name="province">

             <option value="台湾省">台湾省</option>

             <option value="北京市">北京市</option>

             <option value="云南省">云南省</option>

             <option value="南极">南极</option>

          </select>

          <p><input type="submit"value="Get Cities" id="getCities"/></p>

       </div>

       <div class="elem" id="cities">

          <!--显示城市信息的下拉列表框-->

          <select id="citySelection">

          </select>

       </div>

     </form>

  </body>

</html>

 

 

服务器端文件如下:

<%@ page language="java"import="java.util.*" pageEncoding="UTF-8"%>

<%

String path = request.getContextPath();

String basePath =request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

 

<%

  //在该JSP页面不能有其他的标签,否则将不能返回正确的XML文件.

  //因为若该文件中包含HTML或其他标签的话,将会作为HTML或其他文件,而不是纯粹的XML文件;

  //所以Firefox解析返回文件时,会出现http响应为200(OK),但是XML文件却解析错误的现象,如下所示:

  //XML解析错误:废弃document元素之后的内容位置:moz-nullprincipal{uuid}

  //注意uuid是一个128位的二进制数据,用来唯一标识一个com对象.

  HashMap<String,List<String>> province_cities = newHashMap<String, List<String>>();

  ArrayList<String>cities = newArrayList<String>();

  cities.add("台北");

  cities.add("台中");

  cities.add("台南");

  cities.add("高雄");

  province_cities.put("台湾省", cities);

  cities= newArrayList<String>();

  cities.add("海淀区");

  cities.add("朝阳区");

  cities.add("西单");

  province_cities.put("北京市", cities);

  cities= newArrayList<String>();

  cities.add("昆明市");

  cities.add("丽江市");

  cities.add("大理市");

  cities.add("玉溪市");

  cities.add("曲靖市");

  province_cities.put("云南省", cities);

  System.out.println("province_cities="+ province_cities);

  

  request.setCharacterEncoding("UTF-8");

  response.setCharacterEncoding("UTF-8");

  response.setContentType("text/xml; charset=UTF-8");

  //下面这一句不要也可以.

  //response.setHeader("Cache-Control","no-cache");

  

  Stringprovince = request.getParameter("province");

  System.out.println("province="+ province);

  java.io.PrintWriterwriter = response.getWriter();

  if(province_cities.containsKey(province)){

     cities= newArrayList(province_cities.get(province));

     System.out.println("cities="+ cities);

     StringBufferxmlCities = newStringBuffer("<?xml version=\"1.0\"encoding=\"UTF-8\"?>");

     xmlCities.append("<cities>");

     for(String city : cities){

       //其中title是在下拉列表款中显示的城市名称

       //name是城市的名称

       xmlCities.append("<city><title>"+ city +"_title</title><name>"+ city +"</name></city>");

     }

     xmlCities.append("</cities>");

     writer.println(xmlCities);

     writer.flush();

     System.out.println("xmlCities="+ xmlCities);

  }else{

     writer.println("<?xml version=\"1.0\"encoding=\"UTF-8\"?><cities>没有数据!</cities>");

  }

%>


版权声明:本文为coofee原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。