XMLHttpRequest 的基本使用

265 阅读3分钟

简介

XMLHttpRequest 简称 xhr ,是浏览器提供的 Javascript 对象,通过它可以请求服务器上的数据资源jQuery 中的 Ajax 函数,就是基于 xhr 对象封装出来的。

介绍 readyState 属性

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

状态描述
0UNSENTXMLHttpRequest 对象已被创建,但尚未调用 open 方法。
1OPENEDopen() 方法已经被调用。
2HEADERS_RECEIVEDsend() 方法已经被调用,响应头也已经被接收。
3LOADING数据接收中,此时 response 属性中已经包含部分数据。
4DONEAjax 请求完成,这意味着数据传输已经彻底完成或者失败。

发起 GET 请求

发起不带参数的 GET 请求

// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest();

// 2. 调用 open 函数
xhr.open('get', url);

// 3. 调用 send 函数
xhr.send();

// 4. 监听 onreadystatechange 事件
xhr.onreadystatechange = function () {
	// 4.1 监听 xhr 对象的请求状态 readyState ; 与服务器响应状态 status
    if (xhr.readyState !== 4 && xhr.status !== 200) return alert('请求失败');
    
    // 4.2 查看或者使用响应回来的数据
    console.log(xhr.responseText);
}

发起带参数的 GET 请求

发起带参数的 GET 请求只需要修改一步,因为 xhr 目前只有这一种方法来传递 GET 参数。

// ?id=1 就是传递的参数
// 多个参数:?id=1&name=zs&...
xhr.open('get', url + '?id=1');

编码/解码问题

URL 地址中,只允许出现英文相关的字母、标点符号、数字,因此在 URL 地址中不允许出现中文字符,如果 URL 中需要包含中文这样的字符,则必须对中文符号进行编码(转义)

**URL 编码的原则:**使用安全的字符 (没有特殊用途或者特殊意义的可打印字符) 去表示那些不安全的字符。

**通俗理解:**使用英文字符\color{blue}{英文字符}去表示非英文字符\color{blue}{非英文字符}

演示:

http://baidu.com?s=西游
// 经过 URL 编码后
http://baidu.com?s=%E8%A5%BF%E6%B8%B8

解决方法

浏览器提供了 URL 编码与解码的 API

// 编码函数
encodeURL('西游'); // %E8%A5%BF%E6%B8%B8
// 解码函数
decodeURL('%E8%A5%BF%E6%B8%B8'); // 西游

发起 POST 请求

其中增加了设置 Content-Type 属性这一步骤,并且 POST 参数的传递在 send() 函数中进行。

// 1. 创建 xhr 对象
var xhr = new XMLHttpRequest();

// 2. 调用 open 函数
xhr.open('get', url);

// 3. 设置 Content-Type 属性
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

// 4. 调用 send 函数
xhr.send('id=1&name=zs&age=18');

// 5. 监听 onreadystatechange 事件
xhr.onreadystatechange = function () {
	// 5.1 监听 xhr 对象的请求状态 readyState ; 与服务器响应状态 status
    if (xhr.readyState !== 4 && xhr.status !== 200) return alert('请求失败');
    
    // 5.2 查看或者使用响应回来的数据
    console.log(xhr.responseText);
}

注意:XMLHttpRequest返回的数据是字符串,想要进行使用必须经过处理。

以上即是 XMLHttpRequest 的基本使用。

封装 XMLHttpRequest

接下来,我来尝试一下封装一个简易版的 $.ajax() 方法,如果有不正确的地方希望大家指正。

// 封装数据处理函数 将  这样对象类型的数据处理成 id=1&name=zs&age=18 这样的数据
function jointObj(data) {
    var let = [];
    for (let key in data) {
        arr.push(key + '=' + data[key]);
    }
    return arr.join('&');
}
// 最终使用的 ajax 函数
function myAjax(obj) {
    // 1. 创建 xhr 对象
    var xhr = new XMLHttpRequest();
    if (obj.type.toUpperCase() == 'GET') {
        // 2. 调用 open 函数
        xhr.open('GET', obj.url + (obj.data ? '?' + jointObj(obj.data) : ''));
        // 3. 调用 send 函数
        xhr.send();
    } else if (obj.type.toUpperCase() == 'POST') {
        // 2. 调用 open 函数
        xhr.open('POST', obj.url);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        // 3. 调用 send 函数
        xhr.send(jointObj(obj.data));
    }
    // 4. 监听 onreadystatechange 事件
    xhr.onreadystatechange = function () {
        // 4.1 监听 xhr 对象的请求状态 readyState ; 与服务器响应状态 status
        if (xhr.readyState == 4 && xhr.status == 200) {
            // 4.2 查看或者使用响应回来的数据
            // 因为有些接口的数据可能不是个对象,所以我进行了是否是对象的判断
            // 如果是找到 { 符号说明是对象,那就进行类型转换,将字符串转换成对象
            // 如果不是就直接输出
            var result = xhr.responseText.indexOf('{') !== -1 ? JSON.parse(xhr.responseText) : xhr.responseText;
            obj.success(result);
        };
    }
}