The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

解決在 IE 下無法將 HTML/XML 轉成 jQuery 物件的問題

今天在寫一個 Web Service 的測試程式,而我的測試程式是完全用 jQuery 開發的,因為 jQueryAJAX 功能極強,幾乎可以完成所有 Web Service 的測試工作。不過,我這個 Web Service 走的並不是 SOAP 協定,而是客戶自行定義的 XML 格式,所以包括 Request / Response 都是 XML 格式,本想說如此簡單的架構用 jQuery 很方便,結果卻不如我預期的順遂。

首先,我先載入 jQuery ( 參考:網站部署可考慮使用Google AJAX Libraries API 載入JS )

<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" language="javascript">
    google.load("jquery", "1.2");
</script>

然後寫一個簡易的 JavaScript function 幫我發出 HTTP POST 指令:

function SendRequest(RequestURL, RequestXML)
{
    $.post(RequestURL, RequestXML, function(data)
    {
        alert(data);
    });
}

這段程式用了很久沒啥問題,但我今天將這段程式改成讀取 XML 中的某個標籤內的值。我的 Web Service 回應的 XML 格式如下:

<ROOT>
    <ID>123</ID>
    <NAME>This is my name.</NAME>
</ROOT>

所以我將 JavaScript function 改成以下,企圖取得 <ID> 標籤:

function SendRequest(RequestURL, RequestXML)
{
    $.post(RequestURL, RequestXML, function(xml)
    {
        var id = $(xml).find("ID").text();
        alert('id = ' + id);
    });
}

結果我在 IE 執行時,所抓到的 id 值卻永遠都是「空字串」! ( 註:上述程式的重點在於 $(xml) 這一段 )

因為在 jQuery 文件的 API/1.2/Core 的地方有提到 jQuery( html, ownerDocument ) 這種用法,這用法十分方便,可以將一段現有的 HTML Code 直接轉成 jQuery 物件,進而可以利用 jQuery 強大的 API 進行讀取或各式搜尋、編輯、操作。

我直覺上認為這段程式碼應該可以執行,所以我換了 Firefox 測試,果然可以正確的執行,讓我不禁懷疑 IE7 是不是有做了哪些限制,然後又不斷的修改 JavaScript 的寫法,還改用了 jQuery.ajax( options ) 的寫法,當然,還是徒勞無功。

然後,我自己試著用一段最簡單的程式碼測試我的 Code:

alert( $('<ROOT><ID>123</ID></ROOT>').html() );

結果發現,真的在 IE 中完全無法解析,而當我改用正規的 HTML 語法下去試,果然可以用:

alert( $('<div><span>123123</span></div>').html() );

可見 IE 對於 jQuery( html, ownerDocument ) 這個用法上,還真有點龜毛。

最後,我終於研究出真正的問題了,因為我的 Web Service 是用 HTTP Handler 寫的,而我在程式中所指定的 Response.ContentType 是 "text/plain",當我改成 "text/xml" 之後,所有程式就可以在 IE7 下正確執行了!

另外提及一點,在使用 jQuery.post( url, data, callback, type ) 方法開發時,這個方法的最後一個參數 type 指的是回應資料的資料類型,其中包括有 "xml", "html", "script", "json", "jsonp", 與 "text" 等類型,即便你手動修改成 "xml" 而你的 Web Service 回應的資料所設定的 Content-Type 不是 text/xml 的話,在 IE 瀏覽器裡一樣是無法運作的,甚至會造成 JavaScript 執行階段錯誤。當不指定 type 參數時,預設 jQuery 會聰明的自動判斷回應的 Content-Type 自動判斷應解析的資料類型,這部分我是從 jQuery.ajax( options ) 看到的,如下圖:

 jQuery.ajax( options ) - dataType - Intelligent Guess

結論

不管在寫哪種 Web 介面的程式,都要特別重視 Content-Type 的設定,無論是 text/html , text/plain , text/xml 對瀏覽器來說,都是不同的意義,處理的方式也有可能不一樣,當你使用越符合網路標準的方式開發程式,相對的出問題的機率也會越小 (當然有例外)。

相關連結