同事報案,某網頁使用jQuery.ajax()發出四個OData查詢,在Chrome執行正常,在IE時兩個AJAX呼叫正常,有兩個查不到資料。使用F12觀察,發現有問題的AJAX呼叫URL參數包含中文但未使用encodeURIComponent()編碼,Chrome正確地自動做了轉換,IE也自動做了轉換,但轉換結果出現亂碼。

URL未用encodeURIComponent()編碼要承擔敗戰責任無庸置疑,但jQuery.ajax()在不同瀏覽器結果不同這點挺有趣,值得調查,弄了精簡範例驗證這點:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.js">
    </script>
    <script>
        var url = "/_api/Query('執行緒')/items?$filter=Category eq  '黑暗'";
        $.get(url);
    </script>
</body>
</html>

如圖所示,Chrome自動將URL中文部分成功轉成UTF8編碼:

而IE也做了轉換,但轉出亂碼:

換了jQuery 2.2.4甚至3.0.0,測試結果都相同。追入jQuery原始碼,jQuery.ajax()未對URL加工,交給瀏覽器內建XMLHttpRequest物件全權處理,換言之,是IE跟Chrome的XMLHttpRequest行為差異所致。

改寫程式碼如下,直接使用XMLHttpRequest,結果與jQuery.get()完全相同,證實全案的關鍵在於IE與Chrome XHR元件之URL轉換行為不同。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
</head>
<body>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.js">
    </script>
    <script>
        var url = "/_api/Query('執行緒')/items?$filter=Category eq  '黑暗'";
        var oReq = new XMLHttpRequest();
        oReq.open("get", url, true);
        oReq.send();
    </script>
</body>
</html>

結論,URL有中文或特殊字元請自行encodeURIComponent(),不要依賴瀏覽器自動轉換,以免因XHR處理邏輯不同產生非預期結果。


Comments

Be the first to post a comment

Post a comment