jQuery .Ajax() 方法在IE瀏覽器返回No Transport錯誤原因?

在開發環境一切正常,部署至Product Server之後才發現如此錯誤,昨夜爲此煩惱至今日凌晨1:30,經過比對分析,終於發現這是個Cross Site Script問題,即cross-site HTTP Request(跨站點Http請求)引起的。

引用最新jquery-1.6.2.min.js , 我們在.Ajax()方法裏面異步調用了另一個Site的.aspx文件,打算返回一個系統生成的編號,在所有IE6-IE9瀏覽器均提示“ No Transport “,在Firefox瀏覽器卻能夠成功執行到Success返回 ,  網上許多朋友提出例如 在.Ajax()定義前設置jQuery.Support.Cors = true , 經驗證至少在 jquery-1.6.2.min.js 版本不可行;其他還有例如採用jQuery plugin 插件,在.Ajax()執行完畢之前讓其它button等觸發事件暫停等待,這種方法對我們這種情況不可用。

怎樣處理呢? 目前的處理方法一種是採用JSONP可以解決,或者把被調用的.aspx 文件部署在同一個Domain下,同一個站點的不同虛擬目錄也是可以的。

提供測試腳本如下:

        var _url = "http://www.***.net/query.aspx?id=123789";
        $.ajax({
            type: "Get",
            url: _url,
            success: function(response) {
                if (response.toString() != "") {
            ...
                }
            },
        timeout:30000,
        error: function (XMLHttpRequest, txtStatus, errorThrown)
        {
            alert(txtStatus);
        }
        });


/*******************************************

// 2011-11-15 補充

// 關於解決類似問題的思路

// 關於Cross-site-scripting

// 關於JSONP

*******************************************/

有一位James Padolsey的朋友似乎通過重構.ajax方法解決了這個問題,如有興趣可以去看他的原文,源碼也貼在這裏。


/**
 * jQuery.ajax mid - CROSS DOMAIN AJAX
 * ---
 * @author James Padolsey (http://james.padolsey.com)
 * @version 0.11
 * @updated 12-JAN-10
 * ---
 * Note: Read the README!
 * ---
 * @info http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/
 */

jQuery.ajax = (function(_ajax){
    
    var protocol = location.protocol,
        hostname = location.hostname,
        exRegex = RegExp(protocol + '//' + hostname),
        YQL = 'http' + (/^https/.test(protocol)?'s':'') + '://query.yahooapis.com/v1/public/yql?callback=?',
        query = 'select * from html where url="{URL}" and xpath="*"';
    
    function isExternal(url) {
        return !exRegex.test(url) && /:\/\//.test(url);
    }
    
    return function(o) {
        
        var url = o.url;
        
        if ( /get/i.test(o.type) && !/json/i.test(o.dataType) && isExternal(url) ) {
            
            // Manipulate options so that JSONP-x request is made to YQL
            
            o.url = YQL;
            o.dataType = 'json';
            
            o.data = {
                q: query.replace(
                    '{URL}',
                    url + (o.data ?
                        (/\?/.test(url) ? '&' : '?') + jQuery.param(o.data)
                    : '')
                ),
                format: 'xml'
            };
            
            // Since it's a JSONP request
            // complete === success
            if (!o.success && o.complete) {
                o.success = o.complete;
                delete o.complete;
            }
            
            o.success = (function(_success){
                return function(data) {
                    
                    if (_success) {
                        // Fake XHR callback.
                        _success.call(this, {
                            responseText: data.results[0]
                                // YQL screws with <script>s
                                // Get rid of them
                                .replace(/<script[^>]+?\/>|<script(.|\s)*?\/script>/gi, '')
                        }, 'success');
                    }
                    
                };
            })(o.success);
            
        }
        
        return _ajax.apply(this, arguments);
        
    };
    
})(jQuery.ajax);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章