
JFAST.register("ajax.request",
function(a) {
    return function(url, options) {
        var data = options.data || "",
        async = !(options.async === false),
        username = options.username || "",
        password = options.password || "",
        method = (options.method || "POST").toUpperCase(),
        headers = options.headers || {},
        // 基本的逻辑来自lili同学提供的patch
        timeout = options.timeout || 0,
        eventHandlers = {},
        tick,
        key,
        xhr;
        /**
         * readyState发生变更时调用
         * 
         * @ignore
         */
        function stateChangeHandler() {
            if (xhr.readyState == 4) {
                try {
                    var stat = xhr.status;
                } catch(ex) {
                    // 在请求时,如果网络中断,Firefox会无法取得status
                    fire('failure');
                    return;
                }
                fire(stat);
                if ((stat >= 200 && stat < 300) || stat == 304 || stat == 1223) {
                    fire('success');
                } else {
                    fire('error');
                }
                window.setTimeout(function() {
                    xhr.onreadystatechange = JFAST.fn.funcEmpty;
                    if (async) {
                        xhr = null;
                    }
                },
                0);
            }
        }
        /**
         * 获取XMLHttpRequest对象
         * 
         * @ignore
         * @return {XMLHttpRequest} XMLHttpRequest对象
         */
        function getXHR() {
            if (window.ActiveXObject) {
                try {
                    return new ActiveXObject("Msxml2.XMLHTTP");
                } catch(e) {
                    try {
                        return new ActiveXObject("Microsoft.XMLHTTP");
                    } catch(e) {}
                }
            }
            if (window.XMLHttpRequest) {
                return new XMLHttpRequest();
            }
        }
        /**
         * 触发事件
         * 
         * @ignore
         * @param {String} type 事件类型
         */
        function fire(type) {
            var handler = eventHandlers[type],
            globelHandler = JFAST.ajax[type];
            // 不对事件类型进行验证
            if (handler) {
                if (tick) {
                    clearTimeout(tick);
                }
                if (type != 'success') {
                    handler(xhr);
                } else {
                    //处理获取xhr.responseText导致出错的情况,比如请求图片地址.
                    try {
                        var rText = xhr.responseText;
                    } catch(error) {
                        return handler(xhr);
                    }
                    handler(xhr, xhr.responseText);
                }
            } else if (globelHandler) {
                //onsuccess不支持全局事件
                if (type == 'onsuccess') {
                    return;
                }
                globelHandler(xhr);
            }
        }
        for (key in options) {
            eventHandlers[key] = options[key];
        }
        headers['X-Requested-With'] = 'XMLHttpRequest';
        try {
            xhr = getXHR();
            if (method == 'GET') {
                if (data) {
                    url += (url.indexOf('?') >= 0 ? '&': '?') + data;
                    data = null;
                }
                if (options['noCache']) url += (url.indexOf('?') >= 0 ? '&': '?') + 'b' + ( + new Date) + '=1';
            }
            if (username) {
                xhr.open(method, url, async, username, password);
            } else {
                xhr.open(method, url, async);
            }
            if (async) {
                xhr.onreadystatechange = stateChangeHandler;
            }
            // 在open之后再进行http请求头设定
            // FIXME 是否需要添加; charset=UTF-8呢
            if (method == 'POST') {
                xhr.setRequestHeader("Content-Type", (headers['Content-Type'] || "application/x-www-form-urlencoded"));
            }
            for (key in headers) {
                if (headers.hasOwnProperty(key)) {
                    xhr.setRequestHeader(key, headers[key]);
                }
            }
            fire('beforerequest');
            if (timeout) {
                tick = setTimeout(function() {
                    xhr.onreadystatechange = a.fn.blank;
                    xhr.abort();
                    fire("timeout");
                },
                timeout);
            }
            xhr.send(data);
            if (!async) {
                stateChangeHandler();
            }
        } catch(ex) {
            fire('failure');
        }
        return xhr;
    }
});
如果本篇文章帮到了你,那么,请点击右侧的百度分享,让我们一起帮助更多的朋友!

