记录js使用原生 XMLHttpRequest方法 封装http请求,并提供使用实例

1、描述:

复制代码
前端项目中经常会需要http请求,而且很频繁,一般大型项目会使用axios等现成组件兼容性和实用性会很好,但是相对需要安装等比较笨重,所以自己封装了原生 XMLHttpRequest方法,可移植性强。

2、主要功能:

arduino 复制代码
组件透出get,post,put,delete 四个主要的http请求,以及修改baseURL和修改超时请求时间,下面是功能截图:

3、完整代码

javascript 复制代码
class HttpClient {
  constructor(baseUrl) {
    this.baseUrl = baseUrl;
    this.timeout = 30000; // 默认30秒超时
  }

  setBaseUrl(baseUrl) {
    this.baseUrl = baseUrl;
  }

  setTimeout(timeout) {
    this.timeout = timeout;
  }

  // 处理请求参数
  processParams(params) {
    if (!params) return '';
    return Object.entries(params)
      .map(
        ([key, value]) =>
          `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
      )
      .join('&');
  }

  // 发送请求的核心方法
  async sendRequest(method, url, data = null, config = {}) {
    const fullUrl = this.baseUrl ? `${this.baseUrl}${url}` : url;
    const timeout = config.timeout || this.timeout;

    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();

      // 处理GET请求参数
      let requestUrl = fullUrl;
      if (method === 'GET' && data) {
        requestUrl += `?${this.processParams(data)}`;
      }

      xhr.open(method, requestUrl, true);

      // 设置请求头
      const headers = {
        'Content-Type': 'application/json',
        ...config.headers,
      };

      Object.entries(headers).forEach(([key, value]) => {
        xhr.setRequestHeader(key, value);
      });

      // 设置超时
      xhr.timeout = timeout;
      xhr.ontimeout = () => {
        reject({
          code: 'ETIMEDOUT',
          message: `请求超时(${timeout}ms)`,
        });
      };

      // 错误处理
      xhr.onerror = () => {
        reject({
          code: 'NETWORK_ERROR',
          message: '网络错误',
        });
      };

      // 请求状态变化
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          try {
            let responseData;
            if (xhr.responseText) {
              try {
                responseData = JSON.parse(xhr.responseText);
              } catch (e) {
                responseData = xhr.responseText;
              }
            }

            if (xhr.status >= 200 && xhr.status < 300) {
              if (responseData.error.error_no !== '0') {
                reject({
                  code: xhr.status,
                  message: xhr.statusText,
                  data: responseData,
                });
              } else {
                resolve({
                  data: responseData,
                  status: xhr.status,
                  statusText: xhr.statusText,
                });
              }
            } else {
              reject({
                code: xhr.status,
                message: xhr.statusText,
                data: responseData,
              });
            }
          } catch (error) {
            reject({
              code: 'PARSE_ERROR',
              message: '响应解析错误',
              error,
            });
          }
        }
      };

      // 发送请求体
      let requestData = null;
      if (method !== 'GET' && data) {
        if (headers['Content-Type'] === 'application/json') {
          requestData = JSON.stringify(data);
        } else if (
          headers['Content-Type'] === 'application/x-www-form-urlencoded'
        ) {
          requestData = this.processParams(data);
        } else {
          requestData = data;
        }
      }

      xhr.send(requestData);
    });
  }

  // 封装GET请求
  get(url, params = null, config = {}) {
    return this.sendRequest('GET', url, params, config);
  }

  // 封装POST请求
  post(url, data = null, config = {}) {
    return this.sendRequest('POST', url, data, config);
  }

  // 封装PUT请求
  put(url, data = null, config = {}) {
    return this.sendRequest('PUT', url, data, config);
  }

  // 封装DELETE请求
  delete(url, data = null, config = {}) {
    return this.sendRequest('DELETE', url, data, config);
  }
}

// 创建单例实例
const httpClient = new HttpClient();

export default httpClient;

4、使用实例

javascript 复制代码
import httpClient from '../../utils/httpClient';

const smartBaseUrl = 'https://test3.gtjadev.com:8887';

// 设置基础URL
httpClient.setBaseUrl(smartBaseUrl);

// 设置超时时间
httpClient.setTimeout(15000);

// 获取秘钥接口
export async function authlessSecret() {
  return await httpClient.get('/api/smartassistfront/authless/secret/key', '', {
    headers: {
      // Authorization: '',
    },
  });
}

// 异常上报接收接口
export async function abnormalReport(data, headers) {
  return await httpClient.post(
    '/api/smartassistfront/authless/abnormalReport/insert',
    data,
    {
      headers: {
        ...headers,
      },
    }
  );
}

封装的接口使用:

5、结尾

好了,简单的封装了api的请求实例,以后在不同项目中也能直接复用了,尤其是一些比较小的项目,对包大小有限制的一些项目最为实用。

相关推荐
打小就很皮...10 分钟前
Tesseract.js OCR 中文识别
前端·react.js·ocr
qq_1777673720 分钟前
React Native鸿蒙跨平台实现应用介绍页,实现了应用信息卡片展示、特色功能网格布局、权限/联系信息陈列、评分展示、模态框详情交互等通用场景
javascript·react native·react.js·ecmascript·交互·harmonyos
2603_9494621026 分钟前
Flutter for OpenHarmony社团管理App实战:预算管理实现
android·javascript·flutter
wuhen_n32 分钟前
JavaScript内存管理与执行上下文
前端·javascript
Hi_kenyon1 小时前
理解vue中的ref
前端·javascript·vue.js
jin1233222 小时前
基于React Native鸿蒙跨平台地址管理是许多电商、外卖、物流等应用的重要功能模块,实现了地址的添加、编辑、删除和设置默认等功能
javascript·react native·react.js·ecmascript·harmonyos
2501_920931702 小时前
React Native鸿蒙跨平台医疗健康类的血压记录,包括收缩压、舒张压、心率、日期、时间、备注和状态
javascript·react native·react.js·ecmascript·harmonyos
落霞的思绪2 小时前
配置React和React-dom为CDN引入
前端·react.js·前端框架
Hacker_Z&Q2 小时前
CSS 笔记2 (属性)
前端·css·笔记
Anastasiozzzz2 小时前
LeetCode Hot100 295. 数据流的中位数 MedianFinder
java·服务器·前端