XHR、Fetch&Axios详解&网络相关大片文件上传&下载

以下是 XHR(XMLHttpRequest)Fetch API 的全面对比分析,涵盖语法、功能、兼容性等核心差异:


一、语法与代码风格

  1. XHR(基于事件驱动)
    需要手动管理请求状态(如 onreadystatechange 事件)和错误处理,代码冗长且易出现回调地狱。

    const xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://api.example.com/data');
    xhr.onreadystatechange = function() {
         
      if (xhr.readyState === 4 && xhr.status === 200) {
         
        console.log(xhr.responseText);
      }
    };
    xhr.send();
    
  2. Fetch(基于 Promise)
    使用链式调用或 async/await,语法简洁直观,支持现代异步编程模式。

    fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => console.log(data))
      .catch(error => console.error(error));
    

二、核心功能差异

特性 XHR Fetch
错误处理 需手动检查 status 仅网络错误触发 catch,HTTP 错误需通过 response.ok 判断
跨域请求 需设置 withCredentials 默认不支持跨域,需通过 CORS 配置
流式传输 仅部分浏览器支持(如 IE) 原生支持 ReadableStream,适合大文件处理
请求取消 通过 xhr.abort() 实现 需依赖 AbortController
进度监听 支持 onprogress 事件 无原生支持,需通过第三方库实现
Cookie 处理 默认携带 需设置 credentials: 'include'
响应类型 需手动设置 responseType 通过 .json().text() 等方法解析

三、性能与扩展性

  1. XHR
    优点:兼容性好(支持 IE10+),适合需要精细控制请求头、同步请求的场景。
    缺点无法直接处理流数据,内存占用较高。

  2. Fetch
    优点:基于 Promise 和 Stream,支持分块读取数据,减少内存压力。
    缺点默认不处理 Cookie,需手动配置;不支持同步请求


四、适用场景

  1. 优先选择 XHR
    • 需要兼容旧浏览器(如 IE)。
    • 需要实时监听上传/下载进度(如大文件传输)。
    • 需要直接取消请求(如用户中断操作)。

  2. 优先选择 Fetch
    • 现代 Web 应用,追求代码简洁性和可维护性。
    需要流式处理数据(如实时日志或视频流)
    • 与 Service Worker 结合实现离线缓存或请求拦截


五、生态系统与工具

XHR 封装库axios(支持浏览器和 Node.js)、jQuery.ajax
Fetch 封装库redaxios(轻量兼容)、umi-request(企业级功能)。
Polyfill:Fetch 需引入 isomorphic-fetchwhatwg-fetch 支持旧浏览器。


总结

XHR 作为传统 API,适合需要精细控制或兼容性的场景;Fetch 凭借现代化设计和流式处理能力,更适合追求开发效率和性能优化的项目。实际开发中可根据项目需求灵活选择,甚至两者结合使用(如用 axios 兼容 XHR 和 Fetch)。


以下是 XHRFetch 的 GET/POST 请求基础写法及封装方法,结合两种技术的核心特性与最佳实践:


一、原生写法对比

1. XHR 实现

GET 请求

const xhrGet = new XMLHttpRequest();
xhrGet.open('GET', 'https://api.example.com/data?id=1');
xhrGet.onreadystatechange = function() {
   
  if (xhrGet.readyState === 4 && xhrGet.status === 200) {
   
    console.log(JSON.parse(xhrGet.responseText));
  } else if (xhrGet.status >= 400) {
   
    console.error('请求失败:', xhrGet.status);
  }
};
xhrGet.send();

POST 请求

const xhrPost = new XMLHttpRequest();
xhrPost.open('POST', 'https://api.example.com/data');
xhrPost.setRequestHeader('Content-Type', 'application/json');
xhrPost.onreadystatechange = function() {
   
  if (xhrPost.readyState === 4 && xhrPost.status === 201) {
   
    console.log('创建成功:', xhrPost.responseText);
  }
};
xhrPost.send(JSON.stringify({
    name: 'Alice', age: 30 }));
2. Fetch 实现

GET 请求

fetch('https://api.example.com/data?id=1')
  .then(response => {
   
    if (!response.ok) throw new Error(`HTTP错误: ${
     response.status}`);
    return response.json();
  })
  .then(data => console.log(data))
  .catch(error => console.error('请求失败:', error));

POST 请求

fetch('https://api.example.com/data', {
   
  method: 'POST',
  headers: {
    

你可能感兴趣的:(中大厂面试,网络,javascript)