前端手写: Promise封装Ajax

精简版(仅核心功能):

javascript 复制代码
function simpleAjax(url, method = 'GET', data = null) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(method, url, true);
    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(xhr.responseText);
      } else {
        reject(new Error(xhr.statusText));
      }
    };
    xhr.onerror = () => reject(new Error('网络错误'));
    xhr.send(data);
  });
}

完整版

封装说明

  1. 基本功能:支持GET/POST等方法,自动处理JSON数据
  2. 错误处理:包含HTTP状态码、网络错误、超时等错误处理
  3. 响应解析:自动识别JSON响应并解析
  4. 头部支持:可自定义请求头
  5. 扩展性:可根据需要添加超时设置、进度监听等功能
javascript 复制代码
function ajaxPromise(options) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open(options.method || 'GET', options.url, true);
    
    // 设置请求头(可自定义)
    if (options.headers) {
      for (let key in options.headers) {
        xhr.setRequestHeader(key, options.headers[key]);
      }
    }
    
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4) {
        if (xhr.status >= 200 && xhr.status < 300) {
          try {
            const response = xhr.responseText;
            const contentType = xhr.getResponseHeader('Content-Type');
            
            // 自动解析JSON响应
            let data = response;
            if (contentType && contentType.includes('application/json')) {
              data = JSON.parse(response);
            }
            
            resolve({
              data: data,
              status: xhr.status,
              xhr: xhr
            });
          } catch (error) {
            reject(new Error(`解析响应失败: ${error.message}`));
          }
        } else {
          reject(new Error(`请求失败: ${xhr.status} ${xhr.statusText}`));
        }
      }
    };
    
    xhr.onerror = function() {
      reject(new Error('网络错误'));
    };
    
    xhr.ontimeout = function() {
      reject(new Error('请求超时'));
    };
    
    // 发送请求
    if (options.data) {
      let body = options.data;
      if (typeof body === 'object') {
        body = JSON.stringify(body);
        xhr.setRequestHeader('Content-Type', 'application/json');
      }
      xhr.send(body);
    } else {
      xhr.send();
    }
  });
}

// 使用示例
ajaxPromise({
  url: 'https://api.example.com/data',
  method: 'GET'
})
  .then(response => {
    console.log('请求成功:', response.data);
  })
  .catch(error => {
    console.error('请求失败:', error.message);
  });

// POST请求示例
ajaxPromise({
  url: 'https://api.example.com/submit',
  method: 'POST',
  data: { name: '张三', age: 25 },
  headers: {
    'Authorization': 'Bearer token123'
  }
})
  .then(response => console.log('提交成功:', response.data))
  .catch(error => console.error('提交失败:', error));
相关推荐
用户新2 小时前
JS事件深度解析四 事件的循环和异步
前端·javascript·事件·event loop
LIUAWEIO12 小时前
vue里面下载配置使用zepto vue中怎样使用zepto
javascript·vue.js·es6·zepto
lantian13 小时前
TypeScript 三斜线指令完全指南:从入门到理解为什么不再需要它
前端·javascript·vue.js
用户9385156350713 小时前
从"用栈实现队列"说起:深入理解 JavaScript 原型式面向对象
javascript
ZengLiangYi13 小时前
AI 编程工具的数据格式为什么不能统一
javascript·后端·架构
陈_杨13 小时前
鸿蒙APP开发-带你走进旧物集的时间线与收藏管理
前端·javascript
尼斯湖皮皮怪13 小时前
iceCoder双模详解
javascript
小雨下雨的雨13 小时前
月相分析工具鸿蒙PC Electron框架技术实现详解
前端·javascript·华为·electron
布依前端13 小时前
基于 Vue 3 的 Tiptap 富文本编辑器实践:tiptap-editor-vue3 项目介绍
前端·javascript·vue.js
奥利奥夹心脆芙13 小时前
OTel / Logstash / Fluentd 全维对比,及统一日志与指标管道的 AWS ECS 落地
javascript