moonshot 4 - AJAX 2

132 阅读4分钟

前文中,我们简单提到了JQuery为我们封装好的AJAX函数$.get()/$.post()/$.ajax()

其实还有其他的第三方库也为我们封装好了简单易用的AJAX函数,但它们的底层都是在使用XMLHttpRequest这个对象来发起AJAX请求。接下来我们就深入了解一下怎么使用这个对象来完成AJAX操作。

  • XHR的基本使用

xhr的请求状态readyState属性,用来表示当前AJAX请求所处的状态。每个AJAX请求必然处于以下五个状态中的一个:

状态描述
0UNSENTXHR对象已经被创建,但尚未调用open方法
1OPENEDopen()方法已经被调用
2HEADERS_RECEIVEDsend()方法已经被调用,响应头也已经被接收
3LOADING数据接收中,此时response属性中已经包含部分数据
4DONEAJAX请求完成,这意味着数据传输已经彻底成功失败
  1. 发起GET请求
// 1. 创建XHR对象
let xhr = new XMLHttpRequest();
// 2. 调用open函数,指定请求方式与URL地址
xhr.open('GET', 'https://www.juejin.cn/Citizen7');
// 3. 调用send函数,发起AJAX请求
xhr.send();
// 4. 当xhr对象的readyState属性改变的时候调用下面函数
xhr.onreadystatechange = function() {
    // 4.1 监听xhr对象的请求状态readyState与服务器的响应状态status
    if (xhr.readyState === 4 && xhr.status === 200) {
        // 4.2 处理服务器响应回来的数据
        console.log(xhr.responseText);
    };
};

若是想在发起GET请求的同时传递参数呢?——只需要在URL地址后面拼接上我们需要传递的参数,这种叫做查询字符串

...
// 2. 调用open函数,指定请求方式与URL地址
xhr.open('GET','https://www.juejin.cn/Citizen7?id=1&name=lee');
...

值得注意的是,URL地址中只允许出现英文字母、标点符号和数字,不允许出现中文。但如果我们真的需要传递一个中文作为参数,就需要对中文字符进行编码,即URL编码。就像这样:https://www.juejin.cn/Citizen7?id=1&name=%E8%A5%BF%E6%B8%B8%E8%AE%B0

  1. 发起POST请求
// 1. 创建XHR对象
let xhr = new HMLHttpRequest();
// 2. 调用open函数,指定请求方式与URL地址
xhr.open('POST', 'https://www.juejin.cn/Citizen7');
// 3. 设置请求头的Content-Type属性
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 4. 调用send函数,发起AJAX请求,同时将数据以查询字符串的形式提交给服务器
xhr.send('id=1&name=lee');
// 5. 当xhr对象的readyState属性改变的时候调用下面函数
xhr.onreadystatechange = function() {
    // 5.1 监听xhr对象的请求状态readyState与服务器的响应状态status
    if (xhr.readyState === 4 && xhr.status === 200) {
        // 5.2 处理服务器响应回来的数据
        console.log(xhr.responseText);
    };
};
  • 数据交换格式 数据交换格式,就是服务器与客户端之间进行数据传输与交换的格式。

常见的数据交换格式有XMLJSON

  1. XML XML即可拓展标记语言,与HTML类似也是一种标记语言,但这两者没有任何关系。
<note>
    <to>Lee</to>
    <from>May</from>
    <heading>通知</heading>
    <body>晚上开会</body>
</note>    

其实在前端中使用XML作为数据交换格式的情况比较少,主要是因为XML格式臃肿,与数据无关的代码较多,传输效率低,不仅如此,在JS中解析XML也是一件麻烦事。

  1. JSON JSON即JavaScript对象表示法。简单来讲,JSON就是JS对象和数组的字符串表示法,它使用文本来表示一个JS对象或数组,因此JSON的本质就是字符串。JSON与XML相比更小、更快、更容易解析。
{
    "name": "lee",
    "age": 20,
    "gender": "男",
    "address": null,
    "hobby": ["吃饭", "睡觉", "打篮球"]
} 

可以用JSON.parse()JSON字符串转换成JS对象
可以用JSON.stringifyJS对象转换成JSON字符串

  • 封装自己的AJAX
  1. 封装函数
/**
 * 把传入的参数转变成查询字符串的函数
 * @param {data} 需要发送到服务器的数据,是对象形式
 * @returns {string} 返回拼接好的查询字符串
 */
function resovleData(data) {
    let arr = [];
    for (let k in data) {
        // 拼接字符串然后压入到数组中
        arr.push(k + '=' + data[k]);
    }
    // 把数组中的所有元素用 & 连接,然后作为一个字符串返回
    return arr.join('&');
}

/**
 * 封装的AJAX函数
 * @param {options} 配置对象
 */
function myAjax(options) {
    let xhr = new XMLHttpRequest();

    // 把从配置对象里传递过来的参数转变为查询字符串
    let qs = resovleData(options.data);

    if (options.method.toUpperCase() === 'GET') {
        // 发起GET请求
        xhr.open('GET', options.url + '?' + qs);
        xhr.send();
    }
    else if (options.method.toUpperCase() === 'POST') {
        //发起POST请求
        xhr.open('POST', options.url);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send(qs);
    }

    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            // 把响应回来的JSON字符串转变为JS对象
            let result = JSON.parse(xhr.responseText);
            // 调用配置对象里的回调函数,并把请求结果作为参数传入
            options.success(result);
        }
    }
}
  1. 测试
<script>
        myAjax({
            method: 'GET',
            url: 'http://www.liulongbin.top:3006/api/getbooks',
            data: {
                id: 1
            },
            success: function (res) {
                console.log(res);
            }
        });

        myAjax({
            method: 'POST',
            url: 'http://www.liulongbin.top:3006/api/addbook',
            data: {
                bookname: '百年孤独',
                author: '加西亚·马尔克斯',
                publisher: '南海出版社'
            },
            success: function (res) {
                console.log(res);
            }
        });
</script>

3.结果

image.png

  • axios
  1. 什么是axios axios是专注于网络数据请求的第三方库。相比于原生的XMLHttpRequest对象,axios更简单易用。相比于JQuery,axios因为只关注网络请求,所以更加轻量化。

  2. axios的基本使用

    axios.get('url', { params: { /* 参数 */ } }).then(callback);
    axios.post('url', { /* 参数 */ }).then(callback);
    axios({
        method: 'GET',
        url: 'http://www.juejin.cn/Citizen7',
        params: {
            name: 'lee',
            id: 7
        }
    }).then(function(res) {
        /* 成功之后的回调函数,处理传入的请求结果 */
    });
    axios({
        method: 'POST',
        url: 'http://www.juejin.cn/Citizen7',
        data: { // POST的数据需要通过data属性提供
            name: 'lee',
            id: 7
        }
    }).then(function(res) {
        /* 成功之后的回调函数,处理传入的请求结果 */
    });