解決在 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 對瀏覽器來說,都是不同的意義,處理的方式也有可能不一樣,當你使用越符合網路標準的方式開發程式,相對的出問題的機率也會越小 (當然有例外)。

相關連結

  

此文章由 will 發表於 2008/11/19 下午 07:34:26

永久連結 | 評論 (6) | 此文章的RSSRSS comment feed |

分類: ASP.NET | JavaScript | Web

標籤: , , , , ,

收藏:

相關文章

評論

十一月 20. 2008 06:57

黑暗執行緒

熬不過好奇心的鞭策,做了點補充研究:
blog.darkthread.net/.../...g-about-xml-jquery.aspx

黑暗執行緒 tw

十二月 13. 2008 12:30

布丁

web端輸出相關的xml header是非常重要的
很多人都直接把text/xml,application/text/javascript當成text/plain、text/html來使用
ie三不五時會鬼打牆,
尤其DOM物件以及CSS定義的顯示與操作,
像在w3c上面定義DOM物件的操作API,
ie系列不是沒那個function就是結果不正確,
還有textarea從XML物件撈nodeText不能超過4096字元的bug等,
哀~同樣的寫法除了ie外的瀏覽器都正常,
偏偏ie是大宗用戶,又不能當沒看見

M$啊~~還我浪費的工作時間~~

布丁 tw

三月 12. 2009 01:08

西索

$.get(
"User.do?method=getPageXml",
{data:new Date()},
function(xml_)
{
alert(xml_);
$(xml_).find("obj_entiy").each(function(){
var id=$(this).children("entiy_name"); //取对象
var id_value=$(this).children("entiy_name").text(); //取文本 或者 $("id" , xml).text();
alert(id_value);

})

} ,ContentType="text/xml"




)

struts action 设置了
response.setHeader("ContentType","text/xml");

但是在ie中还是有问题 麻烦高手解答一下
回调参数
<?xml version="1.0" encoding="UTF-8"?><page_class><totalitem>0</totalitem><toatlpage>25</toatlpage><begin>0</begin><end>2</end><currentpage>1</currentpage><obj_entiy><entiy_id>1</entiy_id><entiy_name>小朋友0</entiy_name><entiy_addr>0区</entiy_addr><entiy_photo>电话号码0</Entiy_photo></obj_entiy><obj_entiy><entiy_id>2</entiy_id><entiy_name>小朋友1</entiy_name><entiy_addr>1区</entiy_addr><entiy_photo>电话号码1</Entiy_photo></obj_entiy></page_class>

西索 cn

三月 20. 2009 18:40

feng

我用webservice,net中,设置了contenttype还是不行,不知道什么原因,能帮我分析一下吗?你是怎么设置的contenttype?

feng cn

三月 20. 2009 20:11

will

請將你的程式(如下)
response.setHeader("ContentType","text/xml");

修改成以下試試:
response.setHeader("Content-Type","text/xml");

will tw

七月 29. 2009 20:34

Cloud

我在寫CD網頁的時,遇到一樣的問題,但是不可能改header檔,因為是CD上的網頁,後來我找了別的方法處理這個問題。

Cloud tw

新增評論


(將顯示您的Gravatar圖示)  

  Country flag

[b][/b] - [i][/i] - [u][/u]- [quote][/quote]



線上預覽

三月 13. 2010 03:23