AJAX vs Fetch:进度监控与返回数据监控的深度对比

在Web开发中,异步请求是前端与后端交互的核心方式,而AJAX和Fetch作为两大主流方案,在进度监控和返回数据监控方面有着显著差异。本文将从技术原理、代码实现到实际应用场景,为你深度解析两者的区别及选型策略。

一、进度监控:AJAX的天然优势 vs Fetch的曲线救国

1. AJAX的进度监控

AJAX基于XMLHttpRequest对象,通过**onprogress事件**直接实现进度监控,代码简洁直观:

javascript 复制代码
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/large-file');

// 监控下载进度
xhr.onprogress = (event) => {
  if (event.lengthComputable) {
    const percent = (event.loaded / event.total) * 100;
    console.log(`下载进度: ${percent.toFixed(1)}%`);
  }
};

xhr.onload = () => {
  if (xhr.status === 200) {
    console.log('下载完成,数据长度:', xhr.responseText.length);
  }
};
xhr.send();

优势

  • 原生支持:无需额外处理,直接通过事件监听进度。
  • 双向监控 :同时支持上传(xhr.upload.onprogress)和下载进度。
  • 兼容性佳:兼容至IE7,适合需要广泛浏览器支持的场景。

2. Fetch的进度监控

Fetch基于Promise,原生不支持进度监控 ,需通过ReadableStream间接实现:

javascript 复制代码
async function fetchWithProgress(url, onProgress) {
  const response = await fetch(url);
  const total = parseInt(response.headers.get('Content-Length') || 0);
  let loaded = 0;
  const reader = response.body.getReader();

  const stream = new ReadableStream({
    start(controller) {
      function read() {
        reader.read().then(({ done, value }) => {
          if (done) {
            controller.close();
            return;
          }
          loaded += value.length;
          onProgress(loaded, total); // 触发进度回调
          controller.enqueue(value);
          read(); // 继续读取下一块数据
        });
      }
      read();
    }
  });

  return new Response(stream, { headers: response.headers });
}

// 使用示例
fetchWithProgress('https://example.com/large-file', (loaded, total) => {
  console.log(`下载进度: ${Math.round((loaded / total) * 100)}%`);
}).then(response => response.blob());

局限性

  • 代码复杂:需手动处理流数据,逻辑繁琐。
  • 仅支持下载 :上传进度需切换回XMLHttpRequest
  • 兼容性差 :IE不支持ReadableStream,需现代浏览器。

二、返回数据监控:AJAX的实时性 vs Fetch的流式处理

1. AJAX的返回数据监控

AJAX通过onreadystatechange事件监听响应状态,实时获取数据:

javascript 复制代码
xhr.onreadystatechange = () => {
  if (xhr.readyState === 3) { // 数据接收中
    console.log('已接收数据:', xhr.responseText.length);
  } else if (xhr.readyState === 4) { // 请求完成
    if (xhr.status === 200) {
      console.log('完整数据:', xhr.responseText);
    }
  }
};

特点

  • 实时性强:可在数据接收过程中逐步处理(如分页渲染)。
  • 内存友好:避免一次性加载大文件导致内存压力。

2. Fetch的返回数据监控

Fetch通过Response对象获取数据,但默认一次性加载全部内容:

javascript 复制代码
fetch('https://example.com/large-file')
  .then(response => {
    const reader = response.body.getReader();
    const contentLength = parseInt(response.headers.get('Content-Length'));
    let received = 0;

    return new ReadableStream({
      start(controller) {
        function read() {
          reader.read().then(({ done, value }) => {
            if (done) {
              controller.close();
              return;
            }
            received += value.length;
            console.log(`已接收: ${received}/${contentLength} bytes`);
            controller.enqueue(value);
            read();
          });
        }
        read();
      }
    });
  })
  .then(stream => {
    // 处理流式数据(如分块渲染)
  });

特点

  • 流式处理:适合大文件或实时数据流,分块处理降低内存占用。
  • 代码侵入性:需手动管理流,增加复杂度。

三、选型策略:根据项目需求抉择

场景 推荐方案 理由
需简单进度监控 AJAX 原生支持,代码简洁,兼容性好。
需流式处理大文件 Fetch 支持ReadableStream,分块处理内存高效(但需自行实现进度逻辑)。
需现代浏览器特性 Fetch 语法简洁,结合async/await提升可读性(牺牲部分兼容性)。
需上传进度监控 XMLHttpRequest Fetch无原生支持,需混合使用两种API。

四、总结:没有银弹,只有权衡

AJAX和Fetch在进度监控和返回数据监控上各有优劣:

  • AJAX:适合传统项目或对兼容性要求高的场景,进度监控开箱即用。
  • Fetch:适合现代Web应用或需流式处理的场景,但需自行处理进度逻辑。

实际开发中,可结合两者优势(如用Fetch发送请求,用XMLHttpRequest监控上传进度),根据具体需求灵活选型。

相关推荐
空中海34 分钟前
01 React Native 基础、核心组件与布局体系
javascript·react native·react.js
前端之虎陈随易3 小时前
2年没用Nodejs了,Bun很香
linux·前端·javascript·vue.js·typescript
好运的阿财4 小时前
OpenClaw工具拆解之host_workspace_write+host_workspace_edit
前端·javascript·人工智能·机器学习·ai编程·openclaw·openclaw工具
XiYang-DING4 小时前
JavaScript
开发语言·javascript·ecmascript
空中海5 小时前
02 React Native状态、导航、数据流与设备能力
javascript·react native·react.js
空中海6 小时前
02 状态、Hooks、副作用与数据流
开发语言·javascript·ecmascript
空中海6 小时前
04 React Native工程化、质量、发布与生态选型
javascript·react native·react.js
杨超凡7 小时前
豆包收费了?我特么自己用“意念”搓了一个!
javascript
threelab7 小时前
Three.js 咖啡杯烟雾效果 | 三维可视化 / AI 提示词
开发语言·javascript·人工智能