JavaScript使用Fetch网络请求的方法详解

原创 2025-06-07 09:50:46编程技术
356

在前端开发中,网络请求是连接客户端与服务端的核心桥梁。随着现代浏览器的发展,Fetch API 已成为替代传统 XMLHttpRequest 的主流方案。本文ZHANID工具网将系统讲解 Fetch 的使用方法,从基础语法到高级技巧,助你全面掌握这一工具。

一、Fetch 基础语法

1.1 基本 GET 请求

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

关键点解析

  • 返回 Promise 对象,天然支持异步操作

  • 需手动检查 response.ok 判断 HTTP 状态码

  • 使用 response.json() 解析 JSON 响应体

1.2 发送 POST 请求

fetch('https://api.example.com/submit', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    username: 'john_doe',
    password: 'secret123'
  })
})
  .then(response => response.json())
  .then(data => console.log('Success:', data))
  .catch(error => console.error('Error:', error));

重要配置项

  • method: 指定 HTTP 方法(GET/POST/PUT/DELETE 等)

  • headers: 设置请求头(注意 Content-Type 需与 body 格式匹配)

  • body: 请求体内容,支持多种格式(JSON/FormData/Blob 等)

二、响应处理进阶

2.1 响应对象方法

fetch(url)
  .then(response => {
    console.log('Status:', response.status);    // HTTP 状态码
    console.log('Headers:', response.headers.get('Content-Type')); // 获取响应头
    console.log('Redirected:', response.redirected); // 是否重定向
    
    // 根据内容类型选择解析方式
    const contentType = response.headers.get('content-type');
    if (contentType.includes('application/json')) {
      return response.json();
    }
    return response.text();
  });

2.2 错误处理最佳实践

async function fetchData() {
  try {
    const response = await fetch(url);
    
    // HTTP 错误处理
    if (!response.ok) {
      const errorMessage = await response.text();
      throw new Error(`${response.status}: ${errorMessage}`);
    }
    
    const data = await response.json();
    return data;
  } catch (error) {
    console.error('Fetch error:', error);
    // 统一错误处理逻辑
    showErrorNotification(error.message);
  }
}

三、高级功能实现

3.1 并发请求控制

// 使用 Promise.all 处理并发
Promise.all([
  fetch('/api/users'),
  fetch('/api/posts'),
  fetch('/api/comments')
])
.then(responses => Promise.all(responses.map(r => r.json())))
.then(data => {
  const [users, posts, comments] = data;
  // 处理多个响应数据
});

// 使用竞态控制(race)
const timeoutId = setTimeout(() => {
  throw new Error('Request timed out');
}, 5000);

Promise.race([
  fetch(url),
  new Promise((_, reject) => 
    setTimeout(() => reject(new Error('Timeout')), 5000)
  )
])
.finally(() => clearTimeout(timeoutId));

3.2 文件上传

const formData = new FormData();
formData.append('avatar', fileInput.files[0]);
formData.append('userId', '12345');

fetch('/api/upload', {
  method: 'POST',
  body: formData,
  // 无需设置 Content-Type,浏览器会自动设置 multipart/form-data
});

3.3 请求取消

const controller = new AbortController();
const { signal } = controller;

fetch('/api/data', { signal })
  .then(response => {
    // 处理响应
  })
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('请求已取消');
    }
  });

// 取消请求(例如在组件卸载时)
controller.abort();

JavaScript.webp

四、Fetch vs 传统方案对比

特性 Fetch API XMLHttpRequest
语法风格 Promise 链式调用 回调函数
默认携带 Cookie 需显式设置 自动携带
进度监控 不支持 支持 onprogress
超时控制 需手动实现 支持 timeout 属性
浏览器兼容性 IE11+ 需 polyfill 所有浏览器

兼容性处理方案

// 使用 polyfill 支持旧浏览器
import 'whatwg-fetch';

// 或通过条件加载
if (!window.fetch) {
  require('whatwg-fetch').polyfill();
}

五、最佳实践建议

  1. 始终验证响应状态
    Fetch 不会自动拒绝非 2xx 状态码,需手动检查 response.ok

  2. 合理设置请求头

    // 常见安全头设置
    headers: {
      'X-Requested-With': 'XMLHttpRequest',
      'Cache-Control': 'no-cache'
    }
  3. 大文件分片上传

    const chunkSize = 1024 * 1024; // 1MB
    let start = 0;
    
    async function uploadChunk() {
      const chunk = file.slice(start, start + chunkSize);
      const formData = new FormData();
      formData.append('chunk', chunk);
      formData.append('start', start);
      
      const res = await fetch('/upload', {
        method: 'POST',
        body: formData
      });
      
      start += chunkSize;
      if (start < file.size) {
        uploadChunk();
      }
    }
  4. 使用 AbortController 取消请求
    在单页应用路由切换时及时取消进行中的请求

  5. 服务端缓存策略
    通过 Cache-Control 头控制缓存行为:

    fetch(url, { cache: 'force-cache' }); // 强制使用缓存
    fetch(url, { cache: 'reload' });      // 跳过缓存重新请求

六、调试技巧

  1. Chrome DevTools 使用

    • Network 标签页查看请求详情

    • Copy as Fetch 生成代码片段

    • 模拟慢速网络环境测试

  2. 拦截与模拟请求

    // 使用 Service Worker 拦截请求
    self.addEventListener('fetch', event => {
      if (event.request.url.includes('/api/data')) {
        event.respondWith(
          new Response(JSON.stringify({ mockData: true }))
        );
      }
    });
  3. 日志记录中间件

    const logMiddleware = async (url, options) => {
      console.log(`[FETCH] ${options.method} ${url}`);
      const response = await fetch(url, options);
      console.log(`[RESPONSE] ${response.status} ${url}`);
      return response;
    };
    
    // 使用示例
    logMiddleware('/api/data', { method: 'GET' })
      .then(response => response.json())
      .then(console.log);

七、总结

Fetch API 通过现代化的 Promise 接口和更简洁的 API 设计,极大简化了前端网络请求的实现。掌握以下核心要点:

  1. 基础三件套:method/headers/body 配置

  2. 响应处理流程:状态验证 → 内容解析

  3. 高级功能:并发控制、请求取消、文件上传

  4. 错误处理机制:HTTP 错误与网络错误的区分处理

  5. 性能优化:缓存策略、分片上传、请求取消

随着浏览器标准的演进,Fetch 正在持续完善功能(如新增的 keepalive 属性)。建议在实际项目中逐步迁移至 Fetch,对于需要兼容旧浏览器的场景,可结合 axios 等库使用,或在构建流程中加入 polyfill。

JavaScript Fetch 网络请求
THE END
战地网
频繁记录吧,生活的本意是开心

相关推荐

JavaScript 中 instanceof 的作用及使用方法详解
在 JavaScript 的类型检查体系中,instanceof 是一个重要的操作符,用于判断一个对象是否属于某个构造函数的实例或其原型链上的类型。本文ZHANID工具网将系统讲解 instanceof...
2025-09-11 编程技术
503

JavaScript出现“undefined is not a function”错误的解决方法
在JavaScript开发中,TypeError: undefined is not a function 是最常见的运行时错误之一,通常表示代码尝试调用一个未定义(undefined)的值作为函数。本文ZHANID工具网将从...
2025-09-10 编程技术
518

JavaScript报错“Uncaught ReferenceError”如何解决?
在JavaScript开发中,“Uncaught ReferenceError”是常见且易混淆的错误类型。本文ZHANID工具网从错误本质、常见场景、排查步骤、解决方案四个维度,结合真实代码案例与调试技...
2025-09-09 编程技术
566

JavaScript面试题汇总:高频考点与答案解析
在前端开发领域,JavaScript作为核心语言,其面试题覆盖了从基础语法到高级特性的广泛范围。本文ZHANID工具网将系统梳理JavaScript高频面试考点,结合权威资料与典型案例,为...
2025-09-08 编程技术
478

JavaScript中严格模式(use strict)的作用与使用场景
JavaScript的灵活性既是其优势,也是开发者面临的挑战。非严格模式下,隐式全局变量、模糊的this绑定等特性容易导致难以调试的错误。为解决这些问题,ECMAScript 5(ES5)引入...
2025-09-04 编程技术
533

使用JavaScript开发一个简易计算器(附示例代码)
在Web开发领域,JavaScript因其灵活性和强大的交互能力成为实现动态功能的核心技术。本文ZHANID工具网将通过构建一个简易计算器,系统讲解如何利用HTML、CSS和JavaScript完成...
2025-09-03 编程技术
526