【前端面试】手写Ajax、JQuery.ajax以及axios

浏览器需要与服务器进行通信,这个过程是用ajax实现的。

借用一下W3School的描述:
在这里插入图片描述

原生JS手写Ajax

丐版(精简版)

        //将query对象变成可以用在url里的字符串
        function obj2Query(queryObj) {
            let temp = []
            for (key in queryObj) {
                tmp.push(`${encodeURIComponent(key)}=${encodeURIComponent(queryObj[key])}`)
            }
            return temp.join('&')
        }
        function myAjax(url, queryObj, success, error) {
            queryObj = queryObj || {} //防止queryObj === undefined
            url += '?' + obj2Query(queryObj) //根据queryObj拼接出完整的url
            //1. 定义一个xhr
            const xhr = new XMLHttpRequest();
            //2. 开启这个xhr请求,并定义methods,是否异步等信息(默认是true,即异步)
            xhr.open('GET', url, true)
            //3. 绑定onreadystatechange
            xhr.onreadystatechange = function () {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304) {
                        success(xhr.responseText) //具体返回什么看success函数要什么了
                    } else {
                        error(xhr.status) //具体返回什么看error函数要什么了
                    }
                }
            }
            //4. 发送请求
            xhr.send(null) //由于是get请求不传数据,所以是null
        }

简单测试一下:

	<div id="app"></div>
        const app = document.getElementById("app")
        const li = document.createElement('li')
        myAjax('./test.json', { name: "zhangsan" },
            (data) => {
                li.innerHTML = data
                app.appendChild(li)
            },
            (reason) => {
                alert(reason)
            })

设置超时版

        //将query对象变成可以用在url里的字符串
        function obj2Query(queryObj) {
            let temp = []
            for (key in queryObj) {
                temp.push(`${encodeURIComponent(key)}=${encodeURIComponent(queryObj[key])}`)
            }
            return temp.join('&')
        }
        function myAjax(url, queryObj, success, error, timeout) {
            queryObj = queryObj || {} //防止queryObj === undefined
            url += '?' + obj2Query(queryObj) //根据queryObj拼接出完整的url
            //设置一个timer
            let timer;
            //1. 定义一个xhr
            const xhr = new XMLHttpRequest();
            //2. 开启这个xhr请求,并定义methods,是否异步等信息(默认是true,即异步)
            xhr.open('GET', url, true)
            //3. 绑定onreadystatechange
            xhr.onreadystatechange = function () {
                if (timer) clearTimeout(timer)
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304) {
                        success(xhr.responseText) //具体返回什么看success函数要什么了
                    } else {
                        error(xhr.status) //具体返回什么看error函数要什么了
                    }
                }
            }
            //4. 发送请求
            xhr.send(null) //由于是get请求不传数据,所以是null
            //5. 设置超时
            if (timeout) {
                timer = setTimeout(() => {
                    alert('ajax请求超时!')
                    xhr.abort()
                }, timeout)
            }
        }

简单测试一下:

	<div id="app"></div>
        const app = document.getElementById("app")
        const li = document.createElement('li')
        myAjax('./test.json', { name: "zhangsan" },
            (data) => {
                li.innerHTML = data
                app.appendChild(li)
            },
            (reason) => {
                alert(reason)
            }, 2000)

promise版

promise版就不传入successerror两个回调函数了,把它们放到then()catch()里。

        function obj2Query(queryObj) {
            let temp = []
            for (key in queryObj) {
                temp.push(`${encodeURIComponent(key)}=${encodeURIComponent(queryObj[key])}`)
            }
            return temp.join('&')
        }
        function myAjax(url, queryObj, timeout = 2000) {
            const promise = new Promise((resolve, reject) => {
                queryObj = queryObj || {} //防止queryObj === undefined
                url += '?' + obj2Query(queryObj) //根据queryObj拼接出完整的url
                //1. 定义一个xhr
                let timer
                const xhr = new XMLHttpRequest();
                //2. 开启这个xhr请求,并定义methods,是否异步等信息(默认是true,即异步)
                xhr.open('GET', url, true)
                //3. 绑定onreadystatechange
                xhr.onreadystatechange = function () {
                    clearTimeout(timer)
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status <= 300 || xhr.status === 304) {
                            resolve(xhr.responseText) //具体返回什么看then要什么了
                        } else {
                            reject(`status code is ${xhr.status}`) //具体返回什么看catch要什么了
                        }
                    }
                }
                //4. 发送请求
                xhr.send(null) //由于是get请求不传数据
                //5. 设置超时
                if (timeout) { //如果传入了timeout参数
                    timer = setTimeout(() => {
                        console.log('xhr timeout')
                        xhr.abort()
                    }, timeout)
                }
            })
            return promise
        }

简单进行一下测试:

	<div id="app"></div>

首先是返回成功的情况:

        const app = document.getElementById("app")
        const li = document.createElement('li')
        myAjax('./test.json',{name:"zhangsan"},2000).then((data)=>{
            li.innerHTML = data
            app.appendChild(li)
        }).catch((reason)=>{
            alert(reason)
        })

页面上返回:
在这里插入图片描述
故意输错URL的情况:
在这里插入图片描述

jQuery.ajax

jQuery的ajax库比较古老,没有用promise的形式,因此已经逐渐被axios、fetch等更新的库取代。

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>

<body>
    <div id="app"></div>
    <script>
        const app = document.getElementById("app")
        const li = document.createElement('li')
        //jQuery入口函数
        $(function () {
            //请求参数
            var list = {};
            //调用ajax方法
            $.ajax({
                //请求方式
                type: "GET",
                //请求的媒体类型
                contentType: "application/json;charset=UTF-8",
                //请求地址
                url: "./test.json",
                //要输入的参数:
                data: JSON.stringify(list),
                //请求成功的回调函数
                success: function (result) {
                    li.innerHTML = JSON.stringify(result)
                    app.appendChild(li)
                },
                error: function(e){
                    alert(e.status)
                }
            })
        })
    </script>

axios

axios官方文档:http://axios-js.com/docs/
axios是一个基于promise的http供客户端使用的库,可以用在浏览器环境和node环境中。
用封装好的axios写起来非常简洁:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>

<body>
    <div id="app"></div>
    <script>
        const app = document.getElementById("app")
        const li = document.createElement('li')

        // Make a request for a user with a given ID
        axios.get('./test.json', {
            params: {
                user:"zhangsan"
            }
        })
            .then(function (response) {
                // handle success
                li.innerHTML = JSON.stringify(response.data)
                app.appendChild(li)
            })
            .catch(function (error) {
                // handle error
                alert(error.response.status)
            })
            .then(function () {
                // always executed
                alert('axios请求结束')
            });
    </script>
</body>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值