当前位置: 首页 > news >正文

JavaScript HTTP 请求:从老古董到新潮流

前端开发离不开跟后端打交道,HTTP 请求就是这座桥梁。JavaScript 提供了好几种方式来发请求,从老牌的 XMLHttpRequest (XHR) 到现代的 Fetch API,再到各种好用的第三方库(像 Axios、Ky、Superagent)。咱们一个一个聊清楚,带代码示例,讲讲优缺点和实际场景,最后再看看未来趋势。


1. XMLHttpRequest (XHR):老大哥还在用

1.1 啥是 XHR?

XHR 是浏览器内置的 API,最早微软在 IE5 搞出来的,后来成了 Web 标准。虽然现在 Fetch 更时髦,但 XHR 在老项目或者需要兼容古老浏览器的场景里还挺常见。

1.2 特点

  • 异步支持:可以异步发请求,通过事件监听处理结果。
  • 灵活:支持 GET、POST、PUT 等方法,能处理 JSON、文件、甚至二进制数据。
  • 兼容性:几乎所有浏览器(包括 IE)都支持。
  • 缺点:代码写起来有点繁琐,回调风格容易搞成“回调地狱”。

1.3 怎么用?

来看个简单的 GET 请求:

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true); // true 表示异步
xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log(JSON.parse(xhr.responseText)); // 成功拿到数据} else if (xhr.readyState === 4) {console.error('出错了:', xhr.statusText); // 错误处理}
};
xhr.onerror = function () {console.error('网络挂了'); // 网络错误
};
xhr.send();

1.4 POST 请求

如果要发 POST 请求,比如提交个表单数据:

const xhr = new XMLHttpRequest();
xhr.open('POST', 'https://api.example.com/submit', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {console.log('成功:', JSON.parse(xhr.responseText));} else if (xhr.readyState === 4) {console.error('出错了:', xhr.statusText);}
};
const data = JSON.stringify({ name: '小明', age: 25 });
xhr.send(data);

1.5 高级点玩法

  • 超时xhr.timeout = 5000 设置 5 秒超时。
  • 进度监听:用 xhr.onprogress 监听大文件上传/下载进度。
  • 取消请求xhr.abort() 直接干掉请求。

1.6 优缺点

  • 优点:原生支持,兼容性无敌,能监听进度。
  • 缺点:代码啰嗦,回调太多,现代项目用起来有点老土。

2. Fetch API:现代前端的标配

2.1 啥是 Fetch?

Fetch 是浏览器的新 API,2015 年开始推广,基于 Promise 设计,写起来比 XHR 清爽多了。现在基本是前端发请求的首选。

2.2 特点

  • Promise 风格:支持 async/await,代码简洁。
  • 流式处理:可以用 ReadableStream 处理大文件。
  • 现代化:API 设计直观,配置简单。
  • 缺点:不会自动抛 HTTP 错误(像 404、500),得自己检查;不支持进度事件。

2.3 基本用法

简单的 GET 请求:

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

用 async/await 更清爽:

async function fetchData() {try {const response = await fetch('https://api.example.com/data');if (!response.ok) {throw new Error(`HTTP 错误! 状态码: ${response.status}`);}const data = await response.json();console.log(data);} catch (error) {console.error('出错了:', error);}
}
fetchData();

2.4 POST 请求

发个 POST 请求:

async function postData() {try {const response = await fetch('https://api.example.com/submit', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify({ name: '小明', age: 25 }),});if (!response.ok) {throw new Error(`HTTP 错误! 状态码: ${response.status}`);}const data = await response.json();console.log('成功:', data);} catch (error) {console.error('出错了:', error);}
}
postData();

2.5 高级玩法

  • 流式处理:处理大文件或流式数据:
    async function streamData() {const response = await fetch('https://api.example.com/stream');const reader = response.body.getReader();const decoder = new TextDecoder();while (true) {const { done, value } = await reader.read();if (done) break;console.log(decoder.decode(value));}
    }
    
  • 取消请求:用 AbortController
    const controller = new AbortController();
    fetch('https://api.example.com/data', { signal: controller.signal }).then(response => response.json()).then(data => console.log(data)).catch(error => console.error('出错了:', error));
    setTimeout(() => controller.abort(), 3000); // 3秒后取消
    

2.6 优缺点

  • 优点:语法简洁,Promise 好用,支持流式处理,跟现代 JS 配合天衣无缝。
  • 缺点:得手动检查 HTTP 状态码,IE 不支持,没进度事件。

3. 热门请求库:省心省力

原生的 XHR 和 Fetch 虽然好,但有时候写起来还是麻烦。第三方库把这些都封装得更简单,下面聊聊几个 2025 年还很火的库。

3.1 Axios:万金油选择

啥是 Axios?
Axios 是最流行的 HTTP 客户端,支持浏览器和 Node.js,基于 Promise,功能强大,社区活跃。

特点

  • 自动转 JSON 数据。
  • 支持请求/响应拦截器(比如加 token)。
  • 支持取消请求、超时。
  • 兼容性好,连 IE 都支持。
  • GitHub Star(2025 年):大概 100k+。

基本用法

import axios from 'axios';async function fetchWithAxios() {try {const response = await axios.get('https://api.example.com/data');console.log(response.data);} catch (error) {console.error('出错了:', error.message);}
}// POST 请求
async function postWithAxios() {try {const response = await axios.post('https://api.example.com/submit', {name: '小明',age: 25,});console.log('成功:', response.data);} catch (error) {console.error('出错了:', error.message);}
}

拦截器(超实用):

axios.interceptors.request.use(config => {config.headers.Authorization = `Bearer ${token}`;return config;
});axios.interceptors.response.use(response => response,error => {console.error('全局错误:', error);return Promise.reject(error);}
);

优点

  • API 简单,功能全。
  • 支持全局配置,适合大项目。
  • 自动处理 HTTP 错误。

缺点

  • 得引入库,增加点体积(压缩后 ~20KB)。
  • 小项目可能用不上这么多功能。

3.2 Ky:轻量又时髦

啥是 Ky?
Ky 是基于 Fetch 的轻量库,专为现代浏览器设计,API 优雅,体积小。

特点

  • 基于原生 Fetch,无需 polyfill。
  • API 直观,比如 ky.get().json()
  • 体积超小(压缩后 ~5KB)。
  • 支持超时、重试、JSON 自动解析。

基本用法

import ky from 'ky';async function fetchWithKy() {try {const data = await ky.get('https://api.example.com/data').json();console.log(data);} catch (error) {console.error('出错了:', error);}
}// POST 请求
async function postWithKy() {try {const data = await ky.post('https://api.example.com/submit', {json: { name: '小明', age: 25 },}).json();console.log('成功:', data);} catch (error) {console.error('出错了:', error);}
}

重试机制

const data = await ky.get('https://api.example.com/data', {retry: 3,timeout: 5000,
}).json();

优点

  • 超轻量,API 优雅,适合小项目。
  • 学习成本低,现代浏览器完美支持。

缺点

  • 不支持 IE。
  • 功能比 Axios 简单点,拦截器支持有限。

3.3 Superagent:链式调用很酷

啥是 Superagent?
Superagent 是个轻量 HTTP 客户端,支持浏览器和 Node.js,链式调用风格很独特,适合快速上手。

特点

  • 链式 API(像 .get().query())。
  • 支持文件上传、超时、认证。
  • 体积适中(压缩后 ~15KB)。

基本用法

import request from 'superagent';async function fetchWithSuperagent() {try {const response = await request.get('https://api.example.com/data');console.log(response.body);} catch (error) {console.error('出错了:', error.message);}
}// POST 请求
async function postWithSuperagent() {try {const response = await request.post('https://api.example.com/submit').send({ name: '小明', age: 25 });console.log('成功:', response.body);} catch (error) {console.error('出错了:', error.message);}
}

优点

  • 链式调用写起来爽,代码可读性高。
  • 支持多种数据格式。

缺点

  • 社区没 Axios 活跃。
  • 功能比 Axios 少点。

3.4 其他好用的

  • SWR:React 专用的数据获取库,带缓存,超适合动态数据场景。
    import useSWR from 'swr';
    const fetcher = url => fetch(url).then(res => res.json());
    const { data, error } = useSWR('https://api.example.com/data', fetcher);
    
  • React Query (TanStack Query):复杂应用的利器,数据同步和状态管理一流。
  • Alova:新兴库,支持请求策略(缓存、重试),跟 Vue/React 配合好。

4. 对比:选哪个好?

工具原生?Promise?体积拦截器流式处理取消请求兼容性适合场景
XHR无需引入不支持支持支持超强(包括 IE)老项目、兼容性要求高
Fetch无需引入不支持支持支持现代浏览器现代 Web 开发
Axios~20KB支持不支持支持超强(包括 IE)企业级、复杂需求
Ky~5KB有限支持支持现代浏览器轻量项目、现代浏览器
Superagent~15KB有限不支持支持快速开发、中小型项目

选啥?

  • 小项目:Fetch 或 Ky,简单轻量。
  • 大项目:Axios,功能全,省心。
  • React 项目:SWR 或 React Query,数据管理更方便。
  • 兼容 IE:用 XHR 或 Axios。
  • Web3/实时:Fetch 配合 WebSocket 更灵活。

5. 实战:写个请求工具类

下面是个基于 Fetch 和 Axios 的工具类,方便复用,支持 GET、POST、错误处理和超时:

class HttpClient {constructor(baseURL) {this.baseURL = baseURL;this.axiosInstance = axios.create({baseURL,timeout: 10000,});}async fetchRequest(method, url, data = null, options = {}) {try {const response = await fetch(`${this.baseURL}${url}`, {method,headers: {'Content-Type': 'application/json',...options.headers,},body: data ? JSON.stringify(data) : null,...options,});if (!response.ok) {throw new Error(`HTTP 错误! 状态码: ${response.status}`);}return await response.json();} catch (error) {console.error('Fetch 出错了:', error);throw error;}}async axiosRequest(method, url, data = null) {try {const response = await this.axiosInstance({ method, url, data });return response.data;} catch (error) {console.error('Axios 出错了:', error.message);throw error;}}get(url, options = {}) {return this.fetchRequest('GET', url, null, options);}post(url, data, options = {}) {return this.fetchRequest('POST', url, data, options);}axiosGet(url) {return this.axiosRequest('get', url);}axiosPost(url, data) {return this.axiosRequest('post', url, data);}
}// 用法
const client = new HttpClient('https://api.example.com');async function main() {try {const fetchData = await client.get('/data');console.log('Fetch GET:', fetchData);const axiosData = await client.axiosPost('/submit', { name: '小明' });console.log('Axios POST:', axiosData);} catch (error) {console.error('出错了:', error);}
}
main();

6. 注意事项

  1. 错误处理:Fetch 不会自动抛 404、500,得自己检查;Axios 自动抛。
  2. 超时:Fetch 用 AbortController,Axios 直接配 timeout
  3. 安全
    • 用 HTTPS,防止数据泄露。
    • 正确设置 Content-TypeAccept 头。
    • 防 XSS/CSRF,检查 CORS 配置。
  4. 性能
    • 用 SWR 或浏览器 Cache API 缓存数据。
    • 压缩请求体(比如 Gzip)。
    • 用 CDN 加速静态资源。
  5. 调试
    • 浏览器 DevTools 的 Network 面板。
    • Postman 或者 Insomnia 测试 API。
    • Axios 的拦截器可以打日志。

7. 未来趋势

  • GraphQL:越来越多人用 GraphQL 替代 REST,推荐 Apollo Client 或 urql。
  • Server Components:React 19 和 Next.js 15 的服务器组件减少客户端请求,性能更好。
  • WebTransport:新 API,可能取代部分 HTTP 请求,延迟更低。
  • AI 辅助:AI 工具(像 Vercel 的 v0)可能自动生成请求代码,优化 API 调用。

8. 总结

  • XHR:老项目或兼容 IE 用,代码有点烦。
  • Fetch:现代标配,Promise 和流式处理很强,但得手动处理错误。
  • Axios:大项目首选,功能全,社区强。
  • Ky:小项目利器,轻量又好用。
  • Superagent:链式调用爽,适合快速开发。

根据项目需求选工具:小项目用 Fetch/Ky,大项目选 Axios,React 开发试试 SWR 或 React Query。想动手试试?可以拿上面的工具类改改,调个公开 API(比如 JSONPlaceholder)练练手!

点个收藏,关注前端结城,一起用代码点亮前端世界!🚀

http://www.lryc.cn/news/596956.html

相关文章:

  • 在线深凹槽深检测方法都有哪些 —— 激光频率梳 3D 轮廓检测
  • 如何在Pico等Android头显中实现无人机低延迟RTMP全景巡检画面播放
  • 2025年7月份实时最新获取地图边界数据方法,省市区县街道多级联动【文末附实时geoJson数据下载】
  • 从零开始学习Dify-Excel数据可视化(四)
  • 无人机光伏巡检误检率↓78%!陌讯多模态融合算法实战解析
  • 【Android】用 ViewPager2 + Fragment + TabLayout 实现标签页切换
  • Android用户鉴权实现方案深度分析
  • react18更新哪些东西
  • Nginx和Apache的区别
  • Apache PDFBox深入实践
  • Apache JMeter 使用记录踩坑
  • MCP客户端架构与实施
  • Apache POI 介绍与使用指南
  • apache-doris安装兼datax-web配置
  • LNMP-zblog分布式部署
  • 【Unity Shader】Special Effects(十二)Glow 外发光(UI)
  • Unity × RTMP × 头显设备:打造沉浸式工业远控视频系统的完整方案
  • 如何在macOS上修改iPhone的定位
  • ESP32的ADF详解:5. Streams的API
  • 聊聊 Flutter 在 iOS 真机 Debug 运行出现 Timed out *** to update 的问题
  • 在AI深度嵌入企业业务的当下——AI时代的融合数据库
  • Qt 菜单与工具栏设计:提升用户体验
  • AI产品经理面试宝典第48天:产品设计与用户体验优化策略
  • 【数学建模 | Matlab】二维绘图 和 三维绘图
  • 国产数据库转向 “融合” 赛道:电科金仓的下一代形态定义之路
  • Leetcode力扣解题记录--第240题(矩阵搜索)
  • 大规模金融数据相关性并行计算系统设计与实现
  • Linux内存映射原理
  • 第十讲:stack、queue、priority_queue以及deque
  • Python-初学openCV——图像预处理(一)