记录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的请求实例,以后在不同项目中也能直接复用了,尤其是一些比较小的项目,对包大小有限制的一些项目最为实用。

相关推荐
蔗理苦1 小时前
2025-09-05 CSS3——盒子模型
前端·css·css3
二川bro2 小时前
第25节:VR基础与WebXR API入门
前端·3d·vr·threejs
上单带刀不带妹2 小时前
Node.js 的模块化规范是什么?CommonJS 和 ES6 模块有什么区别?
前端·node.js·es6·模块化
缘如风2 小时前
easyui 获取自定义的属性
前端·javascript·easyui
诗书画唱2 小时前
【前端教程】JavaScript 实现图片鼠标悬停切换效果与==和=的区别
开发语言·前端·javascript
光影少年2 小时前
前端上传切片优化以及实现
前端·javascript·掘金·金石计划
喜葵2 小时前
前端安全防护深度实践:从XSS到供应链攻击的全面防御
前端·安全·xss
_r0bin_2 小时前
分片上传-
前端·javascript·状态模式
东北南西2 小时前
手写React状态hook
前端·javascript·react.js
诗书画唱2 小时前
【前端教程】JavaScript DOM 操作实战案例详解
开发语言·前端·javascript