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 虽"老",但在存量项目中依然广泛存在。

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

相关推荐
worxfr2 小时前
Go 并发控制:从 Channel 方向约束到实战模式
开发语言·后端·golang
拾陆楼2 小时前
PT: DMSA辅助调tree报告前后级余量脚本
后端·学习
今天的砖头有点烫手啊2 小时前
接口太慢?Spring Boot 缓存体系 @Cacheable 全链路拆解
spring boot·后端·缓存
雪隐3 小时前
个人电脑玩AI-16让5060 Ti给你打工——MiniMax H3 提速实录:从"泡杯茶等视频"到"视频等你",一张 5060 Ti 的自我修养
前端·人工智能·后端
952363 小时前
Sentinel
java·后端·spring·sentinel·springcloud
名字还没想好☜4 小时前
Go 的 sync.Cond 实战:用条件变量做等待/通知,比忙轮询省 CPU
开发语言·数据库·后端·golang·go
zzzll11114 小时前
Spring Boot 入门指南:从零开始构建微服务
spring boot·后端·微服务
运维行者_4 小时前
企业带宽监控工具实战:网络流量分析与异常排查的5个关键能力
运维·服务器·开发语言·网络·分布式·后端·php
长栎4 小时前
你用了五年的消息队列,不知道它背后站着中介者模式
后端