js GET/POST请求封装

2026-05-28 18:00:27 746阅读 0评论

告别重复造轮子:一套能直接进项目的 JS 请求封装方案

刚接手复杂后台系统时,每个接口都得手写一遍 fetch,配 headers、拆数据、抓网络异常。文件越多,长得一模一样的网络调用代码就越刺眼。与其每次开新页面都去翻旧代码复制粘贴,不如把公共逻辑抽成独立模块。一套合格的请求封装,不是为了堆砌架构名词,而是为了日后换 baseUrl 或加全局鉴权时,不用去上百个组件里手动替换。

落到实际编码阶段,核心只盯住三件事:统一请求入口规范返回数据结构集中拦截异常状态。现代浏览器早已不再依赖 XMLHttpRequest,直接用原生 Fetch 就能搭出生产级骨架。下面按真实业务习惯,把这套逻辑逐层拆开。

先定基础配置。将基础路径与超时阈值抽离为独立变量,后期切换 staging 或 production 环境只需动一行代码。GET 参数适合直拼 URL,POST 则需关注 Payload 序列化。日常开发中尽量统一走 application/json,避开 form-urlencoded 的繁琐转义。若后端强要求传 FormData,留在业务层处理完再丢进封装层更可控。

const BASE_URL = '/api/v1';
const TIMEOUT = 8000;

export function request(method, path, payload = {}) {
  // 自动拼装查询参数
  const url = method === 'GET' && Object.keys(payload).length
    ? `${BASE_URL}${path}?${new URLSearchParams(payload)}`
    : `${BASE_URL}${path}`;

  // 非 GET 请求才携带 body
  const body = (method.toUpperCase() !== 'GET') ? JSON.stringify(payload) : undefined;

  return new Promise((resolve, reject) => {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), TIMEOUT);

    fetch(url, { method, headers: { 'Content-Type': 'application/json' }, body, signal: controller.signal })
      .then(async (res) => {
        clearTimeout(timer);
        if (!res.ok) throw new Error(`服务端异常: ${res.status}`);
        // 统一解包 JSON,业务层直接拿结果
        const result = await res.json();
        resolve(result);
      })
      .catch((err) => {
        clearTimeout(timer);
        reject(err.name === 'AbortError' ? new Error('请求已取消或超时') : err);
      });
  });
}

跑起来之后,工程化的分水岭往往藏在返回值的清洗环节。大多数后端喜欢套 { code, msg, data } 这种三层结构,直接把内层 data 剥离并作为 resolve 值,业务组件就能安心写 await request('POST', '/users/list'),不用在每个页面重复判空。碰到 401 未授权或 403 越权,应在 Promise 链路上统一触发登出或跳转登录态,别让各个视图层自己去猜状态码含义。

网络波动是常态,光靠抛出错误不够。引入请求取消标志与轻量级重试策略能把体验拉回安全线。配合 AbortController 处理路由跳转中断请求,避免内存泄漏;对幂等性接口可尝试指数退避重试两次。若项目规模允许,顺手补上 TypeScript 类型约束,入参校验和返回值推导能提前挡掉大量运行时崩盘。

封装网络层从来不是追求代码行数最少,而是用标准化流程对抗不可控的联调变数。把边界兜底写透,日常迭代时就不用在异步地狱里反复捞 Bug。顺着这个骨架往里填充业务规则,你的前端工程会更稳,写新接口的节奏也会从容不少。

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。

发表评论

快捷回复: 表情:
验证码
评论列表 (暂无评论,746人围观)

还没有评论,来说两句吧...

目录[+]