关于JavaScript的AJAX

Mar 23, 2016

AJAX即“Asynchronous Javascript And XML”!它类似于DHTML或LAMP,AJAX不是指一种单一的技术,而是有机地利用了一系列相关的技术。

概念及特征

相似产物Comet

底层实现 or “传输协议”

var unique = (function () {
    //此方法也可用Math.random()代替
     var time = (new Date()).getTime() + "-",
         i = 1;
     return function () {
        return time + (i++);
     }
 })();

var imgLog = function (url) {
    if (typeof url !== "string" || !url) {
        return;
    }
    var uid = unique();
    var img_id = "_img_" + uid;
    var img = new Image();
    img.hidden = true;
    window[img_id] = img;
    img.onload = img.onerror = function () {//销毁一些对象
        img.onload = img.onerror = null;
        img = undefined;
        delete window[img_id];
    }
    url += url.indexOf("?") == "-1" ? '?_uid=' + uid : '&_uid=' + uid;
    img.src = url;
 };
function success(json) {
    // 成功回调
}

// 创建 script 标签并加入到页面中
var callbackName = ('jsonp_' + Math.random()).replace(".", "");
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
head.appendChild(script);
var timer = setTimeout(function() {
    window[callbackName] = undefined;
    // 如果20s后还未能执行jsonp回调,则认为失败!...
    // 如需要此处可增加异常逻辑处理,errorCallback()
}, 20000);

// 创建jsonp回调函数
// response为jsonp_随机数({JSON数据})
window[callbackName] = function (json) {
    window.clearTimeout(timer);
    head.removeChild(script);
    window[callbackName] = undefined;
    // 执行成功方法
    success(json);
};
//发送请求(callback是和服务端约定的获取回调函数名称的key,而“callback”为大多数情况下的默认值)
script.src = "" + "?callback=" + callbackName;
function createXHR(){
    if(typeof XMLHttpRequest != "undefined"){ // 非IE6浏览器
        return new XMLHttpRequest();
    }else if(typeof ActiveXObject != "undefined"){   // IE6浏览器
        var version = [
            "MSXML2.XMLHttp.6.0",
            "MSXML2.XMLHttp.3.0",
            "Microsoft.XMLHTTP",
        ];
        for(var i = 0; i < version.length; i++){
            try{
                return new ActiveXObject(version[i]);
            }catch(e){
                //异常处理
            }
        }
    }else{
        throw new Error("您的系统或浏览器不支持XHR对象!");
    }
}
// 封装ajax
function createAjax(obj){
    obj = obj || {};
    var xhr = createXHR();
    obj.url = obj.url + "?rand=" + Math.random(); // 防止缓存
    if(obj.method === "get"){      // 判断使用的是否是get方式发送
        obj.url += obj.url.indexOf("?") == "-1" ? "?" + obj.data : "&" + obj.data;
    }

    // 异步的时候需要触发onreadystatechange事件,同步的省略...
    xhr.onreadystatechange = function(){
        // 执行完成
        if(xhr.readyState === 4){
            callBack();
        }
    }
    //open方法的3个参数(HTTP方法或动作, URL, 是否异步)
    xhr.open(obj.method, obj.url, true);

    //设置http头,但大多数的http头信息是无法改变的!
    //application/x-www-form-urlencoded 数据被编码为名称/值对 最常见的格式
    //multipart/form-data 使用表单上传文件时使用
    //application/json 用来告诉服务端消息主体是序列化后的 JSON 字符串
    //text/xml 使用XML作为编码方式的远程调用
    //text/plain 以纯文本形式进行编码

    if (obj.method === "post") {
        xhr.setRequestHeader("Content-Type","application/json");
        xhr.send(obj.data);
    } else {
        xhr.send(null);
    }

    //返回数据
    //同步时,直接调用
    function callBack() {
        // 判断是否返回正确
        if (xhr.status === 200) {
            if (typeof obj.success === "function") {
              obj.success(xhr.response);
            }
        } else {
            if (typeof obj.error === "function") {
                obj.error(xhr.response);
            }
        }
        //xhr.status === 0请求失败
        //xhr.statusText === "abort" 请求被cancle
        //xhr.statusText === "timeout" 请求超时
    }
}

createAjax({
    "method" : "get",
    "url" : "目的URI",
    "data" : '',
    "success" : function(data){
        //成功处理动作
    },
    "error" : function(data){
        //失败处理动作
    }
});