AJAX全称:Asynchronous JavaScript and XML

1. 使用XMLHttpRequest创建
function success(text) {
    console.log('Success:' + text);
}

function fail(code) {
    console.error('Error Code: ' + code);
}

// 新建XMLHttpRequest对象
var request = new XMLHttpRequest();
// 状态发生改变时,执行回调函数
request.onreadystatechange = function() {
    // 判断请求是否完成
    if(request.readyState === 4) {
        // 判断响应结果
        if(request.status === 200) {
            // 请求成功,返回响应数据
            return success(request.responseText);
        } else {
            // 请求失败,返回状态码
            return fail(request.status)
        }
    } else {
        // Http请求还在继续中...
    }
}

// 发送Http请求
request.open('GET', '/api/test');
request.send();

alert('请求已发送,请等待响应...')

要点:

  • 常看浏览器是否支持XMLHttpRequest:window. XMLHttpRequest;
  • 创建XMLHttpRequest对象:var request = new XMLHttpRequest();
  • XMLHttpRequest对象的常用属性

    • onreadystatechange(请求状态是否改变)
    • readyState(请求状态码,4表示请求已完成)
    • status(响应状态码,200表示正确响应)
    • responseText(具体响应内容)
  • XMLHttpRequest对象的常用方法

    • open()(该方法有三个参数)

      • 参数1:指定请求方法(GET / POST / HEAD)
      • 参数2:指定URL(注意:该URL是相对路径
      • 参数3:指定是否异步(true / false),默认为true
    • send()(真正发送请求,该方法有一个参数)

      • 若创建的POST请求,需要传递参数body
      • 若创建的GET请求,可以省略该参数,或传null
2. 使用ActiveXObject创建
// 只需要把XMLHTTPRequest()改为ActiveXObject('Microsoft.XMLHTTP')即可;
var request = new ActiveXObject('Microsoft.XMLHTTP');

因为ActiveXObject对象的属性和方法和XMLHTTPRequest对象是一样的:

// 因此可以整合标准写法和低版本IE上的写法
var request;
if(window.XMLHTTPRequest) {
    request = new XMLHTTPRequest();
} else {
    request = new ActiveXObject('Microsoft.XMLHTTP')
}
3. 使用JQuery创建
var xhr= $.ajax('/api/test',{
    dataType: 'json'
});
// 不需要open() send(), 请求在创建完后即执行
// jQuery创建的xhr对象类似于一个Promise对象
xhr.done((data) => {
    console.log('Success: ' + JSON.stringify(data));
}).fail((xhr, status) => {
    console.error('Error: ' + xhr.status + ', Reason: ' + status);
}).always(() => {
    console.log('请求完成: 无论成功或失败都会调用');
});

要点:

  • $.ajax()方法包含两个参数

    • 参数1:请求URL;
    • 参数2:一个可选的setting对象;
  • setting配置

    • async:是否为异步请求,缺省为true;
    • method:http请求方法,缺省为'GET',还可设为'POST','PUT';
    • headers:额外的http请求头,需为object对象;
    • data:发送的数据,可以为字符串、数组或对象;
    • contentType:发送POST请求的格式,缺省为'application/x-www-form-urlencoded',也可设为'text/plain'、'application/json'等;
    • dataType:接受数据的格式,可以为'html'、'json'、'text'等,缺省值根据contentType自动判定;
  • jQuery ajax语法糖:

    • $.get():发送一个get请求,第二个参数可以为一个object,jq会自动拼接为string

      $.get('api/test',{
          name: 'huang xin',
          age: 18
      })
      // 等价于 /api/test?name=huang%xin&age=18
    • $.post():发送一个post请求,第二个参数缺省被序列化application/x-www-form-urlencoded

      $.post('api/test',{
          name: 'huang xin',
          age: 18
      })
      // 以 name=huang%xin&age=18 作为body发送post请求
    • $.getJSON():发送一个get请求,并返回一个JSON对象;
4. 使用promise创建
// ajax将返回promise对象
function ajax(method, url, data) {
    let request = new XMLHttpRequest();
    return new Promise((resolve,reject) => {
        request.onreadystatechange = () => {
            if(request.readyState === 4) {
                if(request.status === 200) {
                    resolve(request.responseText);
                } else {
                    reject(request.status);
                }
            } 
        }
        request.open(method,url);
        request.send(data);
    });
}
var p = ajax('GET','/api/test');
p.then((text) => {
    // ajax成功,获得响应内容;
    console.log('Success: ' + text);
}).catch((code) => {
    // ajax失败,获得状态码;
    console.error('Error Code: ' + code);
})
练习:使用XHR模拟$.ajax的实现
  • 主函数
var options = {
    url: 'test.me', // 请求地址
    type: 'GET', // 请求方式
    data: {name:'hx', age:18}, // 请求参数
    dataType: 'json', // 数据返回格式
    success: function(text,xml) {
        // 请求成功回调
        // 请求成功后的业务逻辑
    },
    fail: function(status) {
        // 请求失败回调
        // 请求失败后的业务逻辑
    }
}
function ajax(options) {
    // 各step的代码
}
// ajax(options); 实际调用
  • step1:创建
function createXHR() {
    var xhr;
    if(window.XMLHTTPRequest) {
        xhr = new XMLHTTPRequest();
    } else {
        xhr = new ActiveXObject('Microsoft.XMLHTTP')
    }
    return xhr;
}()
  • step2:连接与发送
if(options.type == 'GET') {
    xhr.open('GET',buildGetUrl(options.url,options.data));
    xhr.send();
} else if(options.type == 'POST') {
    xhr.open('POST',options.url);
    xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
    xhr.send(options.data)
} else {
    // 其他请求方法,如:
    // xhr.open('HEAD',options.url);
    // ...
}
  • step3:接收
xhr.onreadystatechange = function() {
    if(xhr.readyState === 4) {
        if(xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
            options.success(xhr.responseText,xhr.responseXML);
        } else {
            options.fail(xhr.status)
        }
    }
}
  • step4:GET参数拼接
buildGetUrl(url,params) {
    for(let item in params) {
        url += (url.includes('?') ? '&':'?');
        url += encodeURIComponent(item) + '=' + encodeURIComponent(params[item]);
    }
    return url;
}

時雨
91 声望6 粉丝

慢慢地把云笔记上的内容搬过来~