手写 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 的底层实现有助于我们更好地理解前端开发的本质。

相关推荐
初心丨哈士奇3 分钟前
基于大模型的GitLab CodeReview 技术调研
前端·人工智能·node.js
Aphasia3118 分钟前
Web身份认证与状态管理:Cookie、Session 与 JWT
前端·面试
鱼樱前端9 分钟前
基于Vue3+Ts+Vant的高级图片上传组件
前端·javascript·vue.js
ChangYan.10 分钟前
electron builder打包时,出现errorOut=ERROR: Cannot create symbolic link
前端·javascript·electron
冴羽23 分钟前
SvelteKit 最新中文文档教程(1)—— 入门指南
前端·javascript·svelte
冬冬小圆帽44 分钟前
防抖和节流
开发语言·前端·javascript
周努力.1 小时前
关于Vue/React中Diffing算法以及key的作用
javascript·vue.js·react.js
lydxwj1 小时前
vue3自定义hooks遇到的问题
前端·javascript·vue.js
野生的程序媛1 小时前
重生之我在学Vue--第8天 Vue 3 UI 框架(Element Plus)
前端·vue.js·ui
前端付杰2 小时前
从Vue源码解锁位运算符:提升代码效率的秘诀
前端·javascript·vue.js