Javascript ajax简介以及简单的Promise封装

254 阅读3分钟

「这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

Javascript ajax简介以及简单的Promise封装

说到ajax大家应该都是非常熟悉的,ajax的出现让在不刷新页面的前提下更新页面成为了可能。不过随着前端技术的发展,现在比较多的还是采用一些流行的HTTP请求库,比如 axios ,而且ES6也原生支持了 fetch() 方法,使用原生ajax开发的情况可能比较少了,但是ajax还是值得去学习的。而且axios和ajax一样,都是基于XMLHttpRequest对象的。

一、Ajax实例的简单实现

1. AJAX请求的几个步骤:

  1. 实例化XMLHttpRequest对象

let xhr = new XMLHttpRequest()

注意在低版本的IE浏览器中不存在XMLHttpRequest对象,需要通过ActiveXObject对象来实现。

let xhr = new ActiveXObject("Microsoft.XMLHTTP");
  1. 打开一个新的HTTP请求,并进行具体的配置(http方法、请求URI和认证信息等)。

这个步骤通过open() 方法来实现 xhrReq.open(method, url, async, user, password);
open方法接受5个参数,分别是请求方法,请求URL,是否是异步请求,用户名,密码。其中后面3个是可选的参数。 平常用的比较多的也就是前面三个。

xhr.open("GET","/index.html",true);
  1. 配置HTTP请求状态变化的回调函数

这个步骤通过 onreadystatechange() 函数来设置回调函数,对不同的readystatestatus设置具体的响应。
注意:

  • 这里的readystate是xhr对象本身的所处的状态,而status是代表http请求的状态码。
  • 只要readystate发生变化,onreadystatechange()函数就会被调用。 最简单的就是在http请求已经完成且请求成功(响应状态码为200)设置请求成功的回调函数。
xhr.onreadystatechange=()=>{
    if(xhr.readyState===4&&xhr.status===200){
        console.log(xhr.responseText);
    }
}
  1. 发送HTTP请求。

配置好了响应的回调函数之后就可以发送了。

这个步骤通过 send() 函数来发送HTTP请求。

xhr.send()
  1. 获取HTTP请求的响应数据。

可以通过responseresponseTextresponseXMLresponseURL来读取响应的信息,具体情况具体分析。

  1. 使用JavaScript和DOM操作实现页面局部刷新。

可以将获取到的响应信息替换到DOM元素中

document.getElementById("myDiv").innerHTML=xhr.responseText;

二、Ajax简单的Promise封装

Promise是ES6中加入的异步编程的解决方案。用Promise对ajax进行封装可以更好地支持异步请求的操作。

以下是简单实现,欢迎大家交流补充。

主要的功能是:

  1. 可以传入自定义配置项,也有默认配置项。
  2. 返回的是一个promise实例,保证异步请求的逻辑。
  3. 对请求参数进行简单处理并根据不同的http方法配置请求header
function ajax_promise(options){
    //地址
    const url=options.url;
    //请求方法
    const method=options.methond.toLocalLowerCase()||'get';
    //默认为异步true
    const async=options.async;
    //请求参数
    const data=options.data;
    //实例化
    let xhr=new XMLHttpRequest();
    //超时时间
    if(options.timeout&&options.timeout>0){
        xhr.timeout=options.timeout;
    }

    return new Promise((resolve,reject)=>{
        xhr.ontimeout=()=>reject&&reject('请求超时');

        //状态变化回调
        xhr.onreadystatechange=()=>{
            if(xhr.readyState==4){
                if(xhr.status>=200&&xhr.status<300||xhr.status==304){
                    resolve && resolve(xhr.responseText)
                }else{
                    reject&&reject();
                }
            }
        }

        //错误回调
        xhr.onerr=err=>reject&&reject();

        let paramArr=[];
        let encodeData;
        //处理请求参数
        if(data instanceof Object){
            for(let key in data){
                paramArr.push(encodeURIComponent(key)+"="+encodeURIComponent(data[key]));
            }
            encodeData=paramArr.join('&');
        }

        //get请求拼接参数
        if(method==='get'){
            //检查url中有没有?以及它的位置
            const index=url.indexOf('?');
            if(index===-1) url+='?';
            else if (index !==url.length -1)  url+='&';
            url += encodeData;
        }
    
        //初始化
        xhr.open(method,url,async);

        if(method ==='get') xhr.send(encodeData);
        else{  //post设置请求头
            xhr.setRequestHeader('Content-Type','application/x-www-form-unlencoded;charset=UTF-8');
            xhr.send(encodeData);
        }
    })
    
}



参考文章:
XMLHttpRequest