盘点前端的那些Ajax请求:从ES5到React

发布时间 2023-12-25 00:05:32作者: 向阳花7

说起前端开发,Ajax请求是绕不开的技术点。然而,程序语言更新换代越来越快,Ajax请求的方式也是各有不同。

在使用ES5开发的时候,我们还在使用最原始的XMLHttpRequest对象:

// createXHR函数,返回浏览器支持的异步请求对象
function createXHR() {
    if(typeof  XMLHttpRequest != "undefined"){
        return new XMLHttpRequest();                                // IE7+、Firefox、Opera、Chrome、Safari
    }
    else if(typeof ActiveXObject != "undefined"){
        return  new ActiveXObject("Microsoft.XMLHTTP");             // IE7及以前版本的浏览器
    }
    else{
        throw new Error("No XHR object available.");
    }
}
var xhr = createXHR();                                                       //创建XHR对象
xhr.onreadystatechange = function(){                                         //readyState状态改变及触发onreadystatechange事件
    if(xhr.readyState == 4){                                                 //readyState状态改变可从0到4,4表示所有数据已就绪
        if((xhr.status >= 200 && xhr.status <300) || xhr.status == 304){     //status为200,响应成功;status为304,表示请求的资源未被修改
            alert(xhr.responseText);                                         //responseText表示响应主体返回的文本
        } else {
            alert("Request was unsuccessful: " + xhr.status);
        }
    }
};
xhr.open("get", "test.php?uid=1&name=xiaoming", true);                            //启动一个请求以备发送
xhr.send(null);

上面是get请求方式。

 发送相同量数据时,get比post快得多,所以如无必要,应尽量使用get请求方式。

post可以发送更多的数据,且不限格式。

post请求需要添加额外的请求头,并把发送数据放在send方法中,如:

xhr.open("post", "test.php", true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");    // post请求需要设置Content-Type
var form = document.getElementById("user");
xhr.send(serialize(form));                                                    // 假如form是一个表单节点,serialize()序列化了表单数据
/* 
    假如需要发送的数据是一个对象,如data,也可以使用JSON.stringify(data)把数据字符串化,在使用send()方法发送
*/

后来出现了JQuery ,极大的简化了Ajax请求的代码编写,几乎只需要一行代码。

$.ajax({
    url: "demo_test.php",
    type: "POST",
    data: {name: 'xiaoming'},
    success: function(result, status, xhr){
        alert(result);
    },
    error: function(result, status, xhr){
        alert('错误:'+status);
    }
});

 单独使用post请求,也可以写成:

$.post("test.php", {uid:'001'}, function(data,status,xhr){
    alert(data);
});

 单独使用get请求,也可以写成:

$.get("test.php",{name: 'xiaom'}, function(data,status,xhr){
    alert("数据: " + data + "\n状态: " + status);
});

到ES6出现的时候,有了新的对象 Promise ,它带有的then和catch方法可以获取异步执行代码的数据,我们就可以把ajax请求获取的数据取出,做我们想要的操作。

根据需要,我们可以把ajax请求放在一个Promise对象中:

function ajax(URL) {
    return new Promise(function (resolve, reject) {
        // createXHR函数,返回浏览器支持的异步请求对象
        function createXHR() {
            if(typeof  XMLHttpRequest != "undefined"){
                return new XMLHttpRequest();                                // IE7+、Firefox、Opera、Chrome、Safari
            }
            else if(typeof ActiveXObject != "undefined"){
                return  new ActiveXObject("Microsoft.XMLHTTP");             // IE7及以前版本的浏览器
            }
            else{
                throw new Error("No XHR object available.");
            }
        }
        var xhr = createXHR();                                                       //创建XHR对象
        xhr.onreadystatechange = function(){                                         //readyState状态改变及触发onreadystatechange事件
            if(xhr.readyState == 4){                                                 //readyState状态改变可从0到4,4表示所有数据已就绪
                if((xhr.status >= 200 && xhr.status <300) || xhr.status == 304){     //status为200,响应成功;
                                                                                     //status为304,表示请求的资源未被修改
                    resolve(xhr.responseText);                                       //responseText表示响应主体返回的文本
                } else {
                    reject("Request was unsuccessful: " + xhr.status);
                }
            }
        };
        xhr.open("get", "test.php?uid=1&name=xiaoming", true);                            //启动一个请求以备发送
        xhr.send(null);
    });
}

获得的数据可以使用then和catch方法处理:

ajax('test.php').then((value) => {
    alert(value);                        // 请求成功
}).catch((error) => {
    alert(error);                        // 请求失败
});

也可以使用async和await获取:

async function getData(){
    try {
        const responceText = await ajax();
        alert(responceText);
    } catch (error) {
        alert(error);                    //输出异常错误
    }
}
getData();

而对于React来说,它是组件化编程方式,ajax请求一般放在生命周期钩子componentDidMount中:

class User extends React.Component {
// ......
    componentDidMount() {
        // 以JQuery的ajax请求举例
        this.serverRequest = $.get('test.php', {uid: '001'},function (result) {
            // 用获取的数据更新组件的state数据
            this.setState({
                username: result.username,
                lastTime: result.lastTime
            });
        }.bind(this));
    }
    // 组件卸载,销毁未结束的请求
    componentWillUnmount() {
        this.serverRequest.abort();
    }
// ......
}