天天看點

解決ajax程式通路伺服器傳回的XML檔案時, firebug出現: XML 解析錯誤問題

解決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[

        var xmlHttpObj= null;

        function catchEvent(eventObj,eventTypeName, eventHandler){

           if(eventObj.addEventListener){

              eventObj.addEventListener(eventTypeName,eventHandler, false);

           }else if(eventObj.attachEvent){

              var event = "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;

        });

        //更健壯的建立跨浏覽器的XMLHttpRequest對象的代碼

        function getXmlHttp(){

           var xmlHttp = null;

           if(window.XMLHttpRequest){

              xmlHttp= new XMLHttpRequest();

           }else{

              try{

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

              }catch(e){

                 try{

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

                 }catch(e){

                    return xmlHttp;

                 }

              }

           }

           return xmlHttp;

        }

        //使用POST方法準備并發送XHR請求

        function populateList(){

           var province =document.getElementById("provinceList").value;

           var url = "../jssource/xml_cities.jsp";

           var query = "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{

                 //擷取顯示城市資訊的下拉清單框

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

                 //在外部XML檔案中也可以使用DOM方法

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

                 //移除citySelection中的所有options節點資料, 将其值為空.

                 citySelection.innerHTML= "";

                 //周遊每個city節點

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

                    var name = null;

                    var title = null;

                    //或者 var name =title = null;

                    var city = cityNodes[i];      

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

                      //elem1中的到的是XML标簽

                      var elem1 = city.childNodes[j].nodeName;

                      //elem2是與elem1标簽對應的資料

                      var elem2 = city.childNodes[j].firstChild.nodeValue;

                      if(elem1 == 'name'){

                         name= elem2;

                      }else{

                         title= elem2;

                      }

                    }

                    //為下拉清單框添加一個新元素

                    citySelection.options[i]= new Option(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 = new HashMap<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>");

   }

%>

繼續閱讀