jQuery AJAX 完整封装教程:告别重复写请求代码

jQuery AJAX 完整封装教程:告别重复写请求代码

在前端项目中,如果你还在每个页面里反复写 $.ajax({ ... }),不仅代码冗余,而且后期维护极其痛苦:接口地址改了要全局替换、loading 逻辑到处复制、错误处理各写各的......

本文将带你从 基础封装 → 统一配置 → 拦截器 → 业务适配 ,一步步打造一个可复用、可维护、可扩展的 jQuery AJAX 请求层。


一、为什么要封装 AJAX?

先看一段"裸写"的 AJAX 代码:

javascript 复制代码
$.ajax({
  url: '/api/user/info',
  type: 'GET',
  dataType: 'json',
  beforeSend: function () {
    $('#loading').show();
  },
  success: function (res) {
    $('#loading').hide();
    if (res.code === 0) {
      console.log(res.data);
    } else {
      alert(res.msg);
    }
  },
  error: function () {
    $('#loading').hide();
    alert('网络错误');
  }
});

问题显而易见:

  • 重复代码极多(loading、错误处理)
  • 接口地址分散,难以管理
  • 响应格式不统一
  • 无法统一做登录失效、权限校验

✅ 封装的目标:

  • 统一请求 / 响应处理
  • 自动携带 token
  • 统一 loading、错误提示
  • 接口集中管理
  • 方便后期替换为 Fetch / Axios

二、最基础的封装:提取公共配置

1️⃣ 基础版本(适合小项目)

javascript 复制代码
function request(options) {
  const defaults = {
    type: 'GET',
    dataType: 'json',
    timeout: 10000,
    beforeSend() {
      console.log('请求开始');
    },
    error(xhr, status) {
      console.error('请求失败:', status);
    }
  };

  const settings = $.extend(true, {}, defaults, options);
  return $.ajax(settings);
}

使用方式:

javascript 复制代码
request({
  url: '/api/user/info',
  success(res) {
    console.log(res);
  }
});

✅ 优点:简单直接

❌ 缺点:loading、token、错误处理仍不够统一


三、进阶封装:统一拦截器思想

我们模仿 Axios 的 请求拦截器 / 响应拦截器​ 思想。


2️⃣ 请求拦截器(统一加 token、loading)

javascript 复制代码
function request(options) {
  const token = localStorage.getItem('token');

  const defaults = {
    type: 'GET',
    dataType: 'json',
    timeout: 10000,
    headers: {
      Authorization: token ? `Bearer ${token}` : ''
    },
    beforeSend(xhr) {
      // 显示 loading
      window.loading && window.loading.show();
    }
  };

  return $.ajax($.extend(true, {}, defaults, options));
}

3️⃣ 响应拦截器(统一处理返回数据)

假设后端返回格式统一为:

css 复制代码
{
  "code": 0,
  "data": {},
  "msg": "success"
}

封装响应处理:

javascript 复制代码
function request(options) {
  const token = localStorage.getItem('token');

  const defaults = {
    type: 'GET',
    dataType: 'json',
    timeout: 10000,
    headers: {
      Authorization: token ? `Bearer ${token}` : ''
    },
    beforeSend() {
      window.loading && window.loading.show();
    }
  };

  return $.ajax($.extend(true, {}, defaults, options))
    .then(res => {
      window.loading && window.loading.hide();

      if (res.code === 0) {
        return res.data; // 直接返回业务数据
      }

      // 业务错误
      return Promise.reject(res.msg);
    })
    .catch(err => {
      window.loading && window.loading.hide();

      if (typeof err === 'string') {
        alert(err);
      } else {
        alert('网络异常,请稍后重试');
      }

      return Promise.reject(err);
    });
}

✅ 调用方只关心业务数据:

ini 复制代码
request({
  url: '/api/user/info'
}).then(data => {
  console.log(data);
});

四、接口集中管理(强烈推荐)

4️⃣ 建立 api.js

css 复制代码
// api.js
const API = {
  getUserInfo: () => request({ url: '/api/user/info' }),
  login: data => request({ url: '/api/login', type: 'POST', data }),
  getOrderList: params => request({ url: '/api/orders', data: params })
};

页面中使用:

ini 复制代码
API.getUserInfo().then(data => {
  $('#username').text(data.name);
});

✅ 好处:

  • 接口地址集中管理
  • 页面代码更干净
  • 后端接口变更,只改一处

五、登录失效 & 权限统一处理

5️⃣ 统一处理 401 / 403

ini 复制代码
.catch(err => {
  window.loading && window.loading.hide();

  if (err.status === 401) {
    alert('登录已过期,请重新登录');
    location.href = '/login';
    return;
  }

  if (typeof err === 'string') {
    alert(err);
  } else {
    alert('请求失败');
  }

  return Promise.reject(err);
});

六、支持 GET / POST / PUT / DELETE 快捷方法

6️⃣ 封装常用方法

kotlin 复制代码
const http = {
  get(url, params) {
    return request({ url, type: 'GET', data: params });
  },
  post(url, data) {
    return request({ url, type: 'POST', data });
  },
  put(url, data) {
    return request({ url, type: 'PUT', data });
  },
  delete(url, params) {
    return request({ url, type: 'DELETE', data: params });
  }
};

使用:

kotlin 复制代码
http.get('/api/user/info').then(data => {
  console.log(data);
});

http.post('/api/login', {
  username: 'admin',
  password: '123456'
});

七、完整最终版封装(推荐直接复制)

javascript 复制代码
// request.js
function request(options) {
  const token = localStorage.getItem('token');

  const defaults = {
    type: 'GET',
    dataType: 'json',
    timeout: 10000,
    headers: {
      Authorization: token ? `Bearer ${token}` : ''
    },
    beforeSend() {
      window.loading && window.loading.show();
    }
  };

  return $.ajax($.extend(true, {}, defaults, options))
    .then(res => {
      window.loading && window.loading.hide();

      if (res.code === 0) {
        return res.data;
      }

      return Promise.reject(res.msg);
    })
    .catch(err => {
      window.loading && window.loading.hide();

      if (err && err.status === 401) {
        alert('登录失效,请重新登录');
        location.href = '/login';
        return;
      }

      if (typeof err === 'string') {
        alert(err);
      } else {
        alert('网络异常,请稍后重试');
      }

      return Promise.reject(err);
    });
}

const http = {
  get(url, params) {
    return request({ url, type: 'GET', data: params });
  },
  post(url, data) {
    return request({ url, type: 'POST', data });
  },
  put(url, data) {
    return request({ url, type: 'PUT', data });
  },
  delete(url, params) {
    return request({ url, type: 'DELETE', data: params });
  }
};

八、封装后的最佳实践总结

✅ **页面中不再出现 $.ajax**​

✅ **所有接口集中在 api.js**​

统一 token、loading、错误处理

后期可无缝迁移到 Axios / Fetch


九、常见扩展思路

  • ✅ 接口缓存(GET 请求)
  • ✅ 请求重试机制
  • ✅ 多语言错误提示
  • ✅ 多 token(普通 / 刷新 token)
  • ✅ Mock 数据支持

十、结语

jQuery 虽"老",但在存量项目中依然广泛存在。

好的封装不是炫技,而是让团队少踩坑、多写业务代码。

相关推荐
IT_陈寒3 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端
唐青枫3 小时前
别把 ArrayList 当成会自动管理内存的 List:Zig 动态数组从入门到实战
后端
鸿蒙开发3 小时前
我为 HarmonyOS 做了一个统一大模型 SDK:@hmkit/ai 正式开源
后端
猪是念来过倒4 小时前
Semaphore 与 RateLimiter:并发控制双雄详解
后端
掘金者阿豪4 小时前
异构数据同步最怕什么?不是同步慢,而是数据对不上
后端
程序员cxuan5 小时前
Claude 官方的学习教程,太强了。
人工智能·后端·程序员
老孙讲技术5 小时前
把工地遮挡和掉线接进项目部:setMessageCallback 订 alarm 与 deviceStatus
后端·物联网·音视频开发
老孙讲技术5 小时前
关店后有人进门,监控值班群却没响:用 setMessageCallback 订 human,再用 aiHuman 打开人形
后端·物联网·音视频开发
LEE5 小时前
原来 Claude Code 最厉害的工具,一行代码都不写
前端·后端
老孙讲技术5 小时前
把园区几百路摄像头收进值班台账:bindDevice 入账与 listDeviceDetailsByPage 翻页
后端·物联网·音视频开发