原生js具体实现Ajax请求的四个步骤

本文介绍了Ajax的定义,强调了其在页面异步通信中的优点和缺点。详细阐述了实现Ajax的四个步骤,包括创建XMLHttpRequest对象、发出HTTP请求、接收数据和更新页面,并提供了一个登录功能的示例。最后提到了如何使用Promise和async函数优化异步处理,以提升代码可读性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是Ajax

全称:Asynchronous JavaScript and XML,它的出现是为了解决修改一点页面信息,而刷新整个页面,Ajax 实现了与服务器的异步通信、局部刷新页面,但它也有着优缺点:
优点:

  • 页面无刷新,在页面内与服务器通信,减少用户等待的时间,增强了用户体验。

  • 使用异步方式与服务器通信,响应速度快

  • 可以把一些原本服务器的工作转接到客户端,利用客户端闲置的能力来处理,减轻了服务器和宽带的负担,节约空间和宽带租用成本

  • 基于标准化的并被广泛支持的技术,不需要下载插件或者小程序

缺点:

  • 无法进行操作的后退,即不支持浏览器的页面后退。

  • 对搜索引擎的支持比较弱。

  • 可能会影响程序中的异常处理机制。

  • 安全问题。对一些网站的攻击,如 CSRF,XXS,SQL 注入等不能很好的防御。

大概实现步骤:

1. 创建 XMLHttpRequest 对象
2. 发出 HTTP 请求
3. 接收服务器传回的数据
4. 更新网页数据

具体示列

这里以登录为列

  1. 先来搭建HTML解构
    css样式这里我就不加了
<div class="wrapper">
        <h2>登录</h2>
        <ul class="login">
            <li><input type="text" id="name" name="username" required><label for="name">用户名</label></li>
            <li><input type="password" id="pwd" name="password" required><label for="pwd">密码</label></li>
            <li><input type="button" value="提交"></li>
        </ul>
    </div>
  1. 下面来js部分

选择器就用jq得写法,核心的不用。

class App {
    constructor() {
    	//初始化
        this.init();
    }

    init() {
    	//渲染页面
        this.render();
        //绑定事件
        this.handler();
    }
    //(因为结构写在html里这就没有生成结构了)
    render() {
    	//选择要使用得节点,添加到生成的对象上
        this.userName = $(".login input[name=username]");
        this.passWord = $(".login input[name=password]");
        this.loginBtn = $(".login input[type=button]");
    }
    //绑定事件都放在这里
    handler() {
        //提交获取页面数据
        this.loginBtn.on("click", this.login)
    }
    ////获取页面数据方法
    login = () =>{}
}
//预备的一个Ajax方法
function ajax(){}
//生成对象
new App();

这里就处理好,发送请求之前的事情了,这准备好了一个login方法,在按钮被点击时调用它,这个方法的作用就是触发Ajax请求。

  1. 写login方法
login = () => {
        //拿到用户输入的值
        let userName = this.userName.val();
        let passWord = this.passWord.val();
        //调用接口,传入数据对象,注册回调函数用于异步处理完成后要执行的
        UserServer.login({
            userName,
            passWord,
            //回调,接收异步的返回值
            callBack({state}) {
                alert(state)
            }
        });

这里的UserServer的对象,是后面要创建的,用来整合所用的ajax请求的,以便统一管理接口。
5.ajax请求
先来创建UserServer的对象

//接口调用管理
const UserServer = {
    //登录接口,接收页面数据,并传入一个回调函数,用于传输数据完成后的操作
    login({
        userName,
        passWord,
        callBack
    }) {
        //调用ajax,传入一个对象包括请求类型,url,具体数据,回调函数
        ajax({
            type: "GET",
            url: "/users/login",
            data: {
                userName,
                passWord
            },
            callBack: callBack
        });
    }
}

这里将具体调用ajax了,确定参数type为请求类型什么,url为访问的具体路径(也就是服务端暴露的接口)这就当后台有这个接口。

6.Ajax具体实现

// ajax函数
function ajax({
    type,
    url,
    data,
    callBack
}) {
    //获取ajax对象
    const xhr = new XMLHttpRequest();

    //监听ajax状态,为4完成,回调函数等待为4执行
    xhr.addEventListener("readystatechange", () => {
        if (xhr.status === 200 && xhr.readyState === 4) {
            //完成请求,拿到数据,调用回调函数callback
            callBack(JSON.parse(xhr.responseText));//转到页面
        }
    })
    //判断请求类型,暂时只考虑get/post
    if (type === "GET") {
        let str = "?";
        for (let k in data) {
            str += `${k}=${data[k]}&`
        }
        //建立连接,get请求数据跟随open传递get类型传递的数据在地址后面
        xhr.open(type, `${url}${str}`);
        xhr.send();
    }else{
        xhr.open(type, `${url}`);
        xhr.send(data);
    }
}

现在Ajax请求已经实现,其他请求,就在UserServer里添加相应的方法,调用Ajax方法传入参数(type,url,data),请求一旦成功就会调用准备好的callback函数,从而回到关于页面的操作的部分,就可以拿到返回值了。

7.用Promise与async函数,来优化(不需要回调函数)

// ajax函数
function ajax({
    type,
    url,
    data,
}) {
    //用Promise封装异步
    return new Promise(resolve => {
        //获取ajax对象
        const xhr = new XMLHttpRequest();

        //监听ajax状态,为4完成,回调函数等待为4执行
        xhr.addEventListener("readystatechange", e => {
            if (xhr.status === 200 && xhr.readyState === 4) {
                //完成请求,拿到数据,调用回调函数callback
                resolve(JSON.parse(xhr.responseText)); //返回结果,结束Promise,回到页面操作
            }
        })
        //判断请求类型,暂时只考虑get/post
        if (type === "GET") {
            let str = "?";
            for (let k in data) {
                str += `${k}=${data[k]}&`
            }
            //建立连接,get请求数据跟随open传递
            xhr.open(type, `${url}${str}`);
            xhr.send();
        } else {
            xhr.open(type, `${url}`);
            xhr.send(data);
        }

    })

}
//接口调用管理
const UserServer = {
    //登录接口,接收页面数据,并传入一个回调函数,用于传输数据完成后的操作
    login : async function({
        userName,
        passWord,
    }){
        //调用ajax,传入一个对象包括请求类型,url,具体数据,回调函数
        return await ajax({
            type: "GET",
            url: "/users/login",
            data: {
                userName,
                passWord
            },
        });
    }
}


class App {
    constructor() {
        this.init();
    }

    init() {
        this.render();
        this.handler();
    }
    render() {
        this.userName = $(".login input[name=username]");
        this.passWord = $(".login input[name=password]");
        this.loginBtn = $(".login input[type=button]");
    }
    handler() {
        //提交获取页面数据
        this.loginBtn.on("click", this.login)
    }

    //获取页面数据方法
    login = async() => {
        let userName = this.userName.val();
        let passWord = this.passWord.val();
        //调用接口,传入数据对象,注册回调函数用于异步处理完成后要执行的
        let state = await UserServer.login({
            userName,
            passWord,
        });
        
        console.log(state)

    }
}

new App();

上面就是全部代码,不太理解用回调函数,就可以用asy函数,它就更像是同步代码,用await关键字来等待异步的返回值。

当然用$.ajax()就更简单了,实际它也是对那些代码的封装,理解其背后的流程,对前后端的交换数据方式方法就会有更深刻的认识。

————纵然是在巨人的肩膀上学习……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值