js实现原生Ajax的封装及ajax原理详解

时间:2024-03-07 09:58:18

原理及概念

AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是一种用于创建快速动态网页的技术。

动态网页:是指可以通过服务器语言结合数据库随时修改数据的网页。

静态网页,随着html代码的生成,页面的内容和显示效果就基本上不会发生变化了——除非你修改页面代码。

AJAX = 异步 JavaScript和XML(标准通用标记语言的子集)。

AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。

Ajax的优势

AJAX 在浏览器与 Web 服务器之间使用异步数据传输(HTTP 请求),这样就可使网页从服务器请求少量的信息,而不是整个页面。

AJAX 可使因特网应用程序更小、更快,更友好。

AJAX 是一种独立于 Web 服务器软件的浏览器技术。

AJAX 基于下列 Web 标准:

JavaScriptXMLHTMLCSS在 AJAX 中使用的 Web 标准已被良好定义,并被所有的主流浏览器支持。AJAX 应用程序独立于浏览器和平台。

Web 应用程序较桌面应用程序有诸多优势;它们能够涉及广大的用户,它们更易安装及维护,也更易开发。

不过,因特网应用程序并不像传统的桌面应用程序那样完善且友好。

通过 AJAX,因特网应用程序可以变得更完善,更友好。

Ajax的异步

异步:是相对于同步而言的,我们学过的定时器也是异步的一种,也就是其他程序不需要等待定时器的代码全部执行完毕以后才能执行代码。因为定时器有可能是无限循环执行代码的,如果等待定时器执行完毕那么其他的代码将永远无法运行。所以异步编程就是相对于其他代码是独立完成的。也就是上面所说的ajax是独立于浏览器平台的。

Tip:事件也是异步执行的,事件是发生某件事情后才会执行代码的。
同步:我们之前所写的代码除了定时器和事件大部分都是同步执行的。也就是同一个代码块中都是从上到下执行的。

Ajax的工作原理

Ajax 核心对象XMLHttpRequest
var _hr=new window.XMLHttpRequest();
通过该实例化的对象向服务器
发出请求,等待服务器响应
服务器响应完成后客户端再处理
服务器端响应的数据。
Ajax请求服务器的过程中有5个状态
0:表示请求服务器之前
1:表示打开远程服务器链接对应open方法
2:表示向服务器发送数据对应send方法
3:表示服务器响应过程中并未结束
4:表示服务器响应完成

/*
 * ajax方法
 */
var Ajax = function() {
    var that = this;
    // 创建异步请求对象方法
    that.createXHR = function() {
        if (window.XMLHttpRequest) { // IE7+、Firefox、Opera、Chrome 和Safari
            return new XMLHttpRequest();
        } else if (window.ActiveXObject) { // IE6 及以下
            var versions = [ \'MSXML2.XMLHttp\', \'Microsoft.XMLHTTP\' ];
            for (var i = 0, len = versions.length; i < len; i++) {
                try {
                    return new ActiveXObject(version[i]);
                    break;
                } catch (e) {
                    // 跳过
                }
            }
        } else {
            throw new Error(\'浏览器不支持XHR对象!\');
        }
    }
    // 初始化数据方法
    that.init = function(obj) {
        // 初始化数据
        var objAdapter = {
            method : \'get\',
            data : {},
            success : function() {
            },
            complete : function() {
            },
            error : function(s) {
                alert(\'status:\' + s + \'error!\');
            },
            async : true
        }
        // 通过使用JS随机字符串解决IE浏览器第二次默认获取缓存的问题
        that.url = obj.url + \'?rand=\' + Math.random();
        that.method = obj.method || objAdapter.method;
        that.data = that.params(obj.data) || that.params(objAdapter.data);
        that.async = obj.async || objAdapter.async;
        that.complete = obj.complete || objAdapter.complete;
        that.success = obj.success || objAdapter.success;
        that.error = obj.error || objAdapter.error;
    }
    // ajax异步调用
    that.ajax = function(obj) {
        that.method = obj.method || \'get\';
        if (obj.method === \'post\') {
            that.post(obj);
        } else {
            that.get(obj);
        }
    }
    // post方法
    that.post = function(obj) {
        var xhr = that.createXHR(); // 创建XHR对象
        that.init(obj);
        that.method = \'post\';
        if (that.async === true) { // true表示异步,false表示同步
            // 使用异步调用的时候,需要触发readystatechange 事件
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) { // 判断对象的状态是否交互完成
                    that.callback(obj, this); // 回调
                }
            };
        }
        // 在使用XHR对象时,必须先调用open()方法,
        // 它接受三个参数:请求类型(get、post)、请求的URL和表示是否异步。
        xhr.open(that.method, that.url, that.async);
        // post方式需要自己设置http的请求头,来模仿表单提交。
        // 放在open方法之后,send方法之前。
        xhr.setRequestHeader(\'Content-Type\',
                \'application/x-www-form-urlencoded\');
        xhr.send(that.data); // post方式将数据放在send()方法里
        if (that.async === false) { // 同步
            that.callback(obj, this); // 回调
        }
    };
    // get方法
    that.get = function(obj) {
        var xhr = that.createXHR(); // 创建XHR对象
        that.init(obj);
        if (that.async === true) { // true表示异步,false表示同步
            // 使用异步调用的时候,需要触发readystatechange 事件
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) { // 判断对象的状态是否交互完成
                    that.callback(obj, this); // 回调
                }
            };
        }
        // 若是GET请求,则将数据加到url后面
        that.url += that.url.indexOf(\'?\') == -1 ? \'?\' + that.data : \'&\'
                + that.data;
        // 在使用XHR对象时,必须先调用open()方法,
        // 它接受三个参数:请求类型(get、post)、请求的URL和表示是否异步。
        xhr.open(that.method, that.url, that.async);
        xhr.send(null); // get方式则填null
        if (that.async === false) { // 同步
            that.callback(obj, this); // 回调
        }
    }
    // 请求成功后,回调方法
    that.callback = function(obj, xhr) {
        if (xhr.status == 200) { // 判断http的交互是否成功,200表示成功
            obj.success(xhr.responseText); // 回调传递参数
        } else {
            alert(\'获取数据错误!错误代号:\' + xhr.status + \',错误信息:\' + xhr.statusText);
        }
    }
    // 数据转换
    that.params = function(data) {
        var arr = [];
        for ( var i in data) {
            // 特殊字符传参产生的问题可以使用encodeURIComponent()进行编码处理
            arr.push(encodeURIComponent(i) + \'=\' + encodeURIComponent(data[i]));
        }
        return arr.join(\'&\');
    }
    return {
        post : that.post,
        get : that.get,
        ajax : that.ajax
    }
}

将以上代码写入一个js文件中,在HTML文件引用。

封装ajax使用案例:

Ajax().post({

  url: \'ajax.php\',
    data: {
    \'name\': \'JR\',
    \'age\': 22
  },
  success: function(message) {
  console.log(message);
},
async: true
});



function
listPrain() { Ajax() .post( { url : \'fileMana/listSite/\', success : function(data) { var items = JSON.parse(data); if (items.data.length > 0) { for (var i = 0; i < items.data.length; i++) { $("#sid").append( "<option value=\'" + items.data[i].id + "\'>" + items.data[i].prain + "</option>"); } } else { // 无可用站点 } $(document).ready(function() { $(\'#sid\').multiselect(); }); }, async : true }); }