手写 AJAX:从零实现一个简洁的异步请求函数

手写 AJAX:从零实现一个简洁的异步请求函数

前言

在现代前端开发中,fetchaxios 等工具库已经大大简化了异步请求的编写。但在某些情况下,我们仍然需要深入了解 AJAX 的底层实现,尤其是在学习 JavaScript 语言核心的过程中。今天,我们将从零开始,手写一个 AJAX 请求函数,并封装成一个基于 PromisegetJSON 方法。

什么是 AJAX?

AJAX(Asynchronous JavaScript and XML)是一种用于创建异步 Web 应用的技术,允许网页在不重新加载的情况下从服务器获取数据。现代 AJAX 主要使用 JSON 作为数据格式,而不是早期的 XML。

手写 AJAX 请求

以下是我们手写的 getJSON 方法,它通过 XMLHttpRequest 发送 GET 请求,并返回 Promise 以支持异步操作。

代码实现

xml 复制代码
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>手写Ajax</title>
</head>
<body>
    <script>
        const getJSON = function(url) {
            return new Promise((resolve, reject) => {
                const xhr = window.XMLHttpRequest
                    ? new XMLHttpRequest()
                    : new ActiveXObject("Microsoft.XMLHTTP"); // 兼容早期IE浏览器
                
                xhr.open('GET', url, true);
                xhr.onreadystatechange = function() {
                    if (xhr.readyState !== 4) return;
                    if (xhr.status === 200 || xhr.status === 304) {
                        resolve(JSON.parse(xhr.responseText)); // 解析 JSON 数据
                    } else {
                        reject(new Error(`请求失败,状态码:${xhr.status}`));
                    }
                };
                xhr.send();
            });
        };

        getJSON('https://api.github.com/orgs/lemoncode/members')
        .then(data => {
            console.log("请求成功:", data);
        })
        .catch(error => {
            console.error("请求失败:", error);
        });
    </script>
</body>
</html>

代码解析

  1. 兼容性处理

    • 通过 window.XMLHttpRequest 选择 XMLHttpRequest,如果浏览器不支持(如 IE 早期版本),则使用 ActiveXObject
  2. 创建异步请求

    • xhr.open('GET', url, true); 这里的 true 代表异步操作。
  3. 监听 readystatechange 事件

    • xhr.readyState === 4 代表请求已完成。
    • xhr.status === 200 || xhr.status === 304 代表请求成功。
    • 解析 JSON 数据后返回。
  4. 使用 Promise

    • 通过 resolve 返回数据,reject 处理错误,增强可读性。

对比 fetch API

fetch 是现代浏览器提供的原生 API,它可以用更简洁的方式来实现相同的功能,例如:

ini 复制代码
fetch('https://api.github.com/orgs/lemoncode/members')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

相比之下,fetch 语法更简洁,且默认返回 Promise,不需要手动封装。但理解 XMLHttpRequest 的底层实现对于深入学习 JavaScript 仍然很有帮助。

总结

本篇文章带你从零实现了一个 getJSON 方法,它使用 XMLHttpRequest 进行 AJAX 请求,并通过 Promise 进行封装,使得代码更易读、更符合现代 JavaScript 编程风格。虽然现在我们更多使用 fetchaxios,但掌握 AJAX 的底层实现有助于我们更好地理解前端开发的本质。

相关推荐
CharlesYu017 小时前
前端性能优化的第一性原理,是不断缩短“用户发起意图 → 获得可用结果”之间的时间
前端
平头哥技术团队8 小时前
Day 21 _ 页内锚点_给每段起个 id,目录写 href=_#id_,点一下页面就滚到那一段
前端·html·html5
子兮曰9 小时前
Bun v1.4.1 深度解析:从 Zig 到 Rust,一场 11 天、64 个 AI 代理的语言迁徙
前端·后端·bun
人民广场吃泡面9 小时前
什么是AI Agent?它又能给前端带来哪些效率提升?
前端·人工智能
中科三方10 小时前
两家域名注册商资质被ICANN终止:企业域名资产安全再受关注
前端·网络·安全·域名
bug总结10 小时前
uniapp vue3全局方法注册使用
前端·javascript·uni-app
华无丽言10 小时前
如何在宜搭中实现获取子表中的字段值赋值到父表中?
前端·javascript·低代码
IT_陈寒11 小时前
Vue的computed属性竟然坑了我一把
前端·人工智能·后端
威斯软科的老司机11 小时前
通俗讲解 CNN 图像识别、向量 Embedding、Softmax 概率计算这三块的简化原理
前端·人工智能·ui·数字孪生
2601_9623824311 小时前
剑指大前端全栈工程师(全2册)主要情节
javascript·实战案例·全栈工程师·剑指大前端·html5+css3