AJAX 解析与高频问题

发布于:2025-08-02 ⋅ 阅读:(9) ⋅ 点赞:(0)

一、AJAX 核心概念

AJAX (Asynchronous JavaScript and XML) 是一种无需重新加载整个页面的情况下,与服务器交换数据并更新部分网页的技术。

核心特点:

  • 异步通信:不阻塞用户操作
  • 局部更新:仅刷新页面部分内容
  • 数据格式:现代主要用 JSON,早期用 XML
  • 跨平台:基于标准 JavaScript 和 XMLHttpRequest

二、原生 AJAX 实现流程

1. 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
2. 配置请求
xhr.open('GET', 'https://api.example.com/data', true); // 异步请求
3. 设置回调函数
xhr.onload = function() {
  if (xhr.status >= 200 && xhr.status < 300) {
    console.log(JSON.parse(xhr.responseText));
  } else {
    console.error('请求失败:', xhr.statusText);
  }
};

xhr.onerror = function() {
  console.error('网络错误');
};
4. 发送请求
xhr.send();
5. 带 POST 数据的示例
xhr.open('POST', '/api/submit');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ name: 'Alice' }));

三、Fetch API(现代替代方案)

fetch('https://api.example.com/data')
  .then(response => {
    if (!response.ok) throw new Error('Network error');
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

对比 XMLHttpRequest:

特性 Fetch API XMLHttpRequest
链式调用 ✅ Promise-based ❌ 回调嵌套
默认不带Cookie ✅ 需配置 credentials ✅ 默认携带
取消请求 ❌ 需 AbortController ✅ xhr.abort()

四、高频问题

1、基础篇
Q: AJAX 的全称是什么?核心作用?

    Asynchronous JavaScript And XML,实现异步数据加载和局部更新。

Q: XMLHttpRequest 的 readyState 有哪几种状态?

        0: 未初始化

        1: 已打开连接

        2: 已接收响应头

        3: 下载响应体中

        4: 请求完成

Q: 如何解决 AJAX 的跨域问题?

        CORS (服务端设置 Access-Control-Allow-Origin)

        JSONP (仅限 GET)

        代理服务器 (Nginx 反向代理)
2、进阶篇
Q: Fetch 和 AJAX 的主要区别?

        Fetch 基于 Promise,XHR 基于事件

        Fetch 需要手动处理错误(不会 reject HTTP 错误状态码)

        Fetch 默认不发送/接收 Cookies

Q: 如何取消一个 AJAX 请求?
// XHR
const xhr = new XMLHttpRequest();
xhr.abort(); // 取消

// Fetch
const controller = new AbortController();
fetch(url, { signal: controller.signal });
controller.abort(); // 取消
Q: 什么是 AJAX 的 CSRF 攻击?如何防御?

        攻击原理:利用用户已登录状态伪造请求

        防御措施:

            同源检测

            CSRF Token

            SameSite Cookie
3、原理篇
Q: 手写一个简易的 AJAX 封装函数
function myAjax({ method = 'GET', url, data, headers }) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url);
    for (const key in headers) {
      xhr.setRequestHeader(key, headers[key]);
    }
    xhr.onload = () => resolve(JSON.parse(xhr.responseText));
    xhr.onerror = () => reject(xhr.statusText);
    xhr.send(JSON.stringify(data));
  });
}
Q: 解释 AJAX 的长轮询(Long Polling)与 WebSocket 的区别

        长轮询:客户端发起请求,服务器保持连接直到有数据返回

        WebSocket:全双工通信,服务端可主动推送

五、实际应用场景

1. 表单提交无刷新
document.getElementById('myForm').addEventListener('submit', function(e) {
  e.preventDefault();
  fetch('/submit', {
    method: 'POST',
    body: new FormData(this)
  }).then(/* 处理响应 */);
});
2. 无限滚动加载
window.addEventListener('scroll', function() {
  if (window.innerHeight + window.scrollY >= document.body.offsetHeight - 500) {
    fetch('/more-items').then(/* 追加内容 */);
  }
});

六、调试与优化技巧

查看 AJAX 请求

    Chrome 开发者工具 → Network 面板

    过滤 XHR/Fetch 请求

性能优化

    合并请求(如 GraphQL)

    缓存响应结果
const cachedData = localStorage.getItem('apiData');
if (cachedData) {
  render(JSON.parse(cachedData));
} else {
  fetch('/data').then(data => {
    localStorage.setItem('apiData', JSON.stringify(data));
    render(data);
  });
}

七、实战题

题目:实现一个带重试机制的 AJAX 请求函数

function fetchWithRetry(url, maxRetries = 3, delay = 1000) {
  return new Promise((resolve, reject) => {
    const attempt = (retryCount) => {
      fetch(url)
        .then(resolve)
        .catch(error => {
          if (retryCount >= maxRetries) return reject(error);
          setTimeout(() => attempt(retryCount + 1), delay);
        });
    };
    attempt(0);
  });
}

八、现代替代技术

技术 特点 适用场景
GraphQL 单请求获取多资源 复杂数据关联查询
WebSocket 全双工实时通信 聊天室、股票行情
Server-Sent Events 服务端单向推送 实时通知(如新闻推送)

网站公告

今日签到

点亮在社区的每一天
去签到