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监控上传进度),根据具体需求灵活选型。

相关推荐
Face2 分钟前
路由Vue-router 及 异步组件
前端·javascript·vue.js
ArcX3 分钟前
从 JS 到 Rust 的旅程
前端·javascript·rust
技术小丁5 分钟前
使用 HTML + JavaScript 实现自定义富文本编辑器开发实践(附完整代码)
前端·javascript·html
轻语呢喃1 小时前
DeepSeek 接口调用:从 HTTP 请求到智能交互
javascript·deepseek
风之舞_yjf1 小时前
Vue基础(14)_列表过滤、列表排序
前端·javascript·vue.js
belldeep2 小时前
QuickJS 如何发送一封邮件 ?
javascript·curl·smtp·quickjs
Jiaberrr2 小时前
uniapp Vue2 获取电量的独家方法:绕过官方插件限制
前端·javascript·uni-app·plus·电量
Joker`s smile3 小时前
使用React+ant Table 实现 表格无限循环滚动播放
前端·javascript·react.js
然我3 小时前
从原生 JS 到 React:手把手带你开启 React 业务开发之旅
javascript·react.js·前端框架
wkj0013 小时前
QuaggaJS 配置参数详解
java·linux·服务器·javascript·quaggajs