原生XMLHttpRequest 封装 可上传formData格式数据

本文介绍了一个使用JavaScript实现的AJAX封装函数,包括GET、POST、PUT、DELETE和CANCEL请求方法,以及处理超时和错误的机制。函数提供了一致的接口,便于在项目中管理网络请求。
摘要由CSDN通过智能技术生成

该封装的请求 包含 get post put delete cancel(取消请求)完成取消请求 

const baseUrl = "http://192.168.1.34:5555";

/**
 * @function createXhrRequest
 * @param {String} baseUrl 基础url
 * @param {Number} timeout 超时时间
 * @param {Object} defaultData 默认参数
 * @param {Object} head 请求头
 * @return {Object}
 */
const createXhrRequest = (
  {
    head = {},
    baseUrl = '',
    timeout = 30000,
    defaultData = {},
  } = {}) => {
  const isEmptyObject = (obj) => obj && Object.keys(obj).length === 0 && obj.constructor === Object;

  const success = (resolve, res) => {
    if (res.code === 200) {
      resolve(res);
    } else {
      utils.msg.error(res.msg);
      reject(res);
    }
  }

  const error = (reject, err) => {
    if (err.status === 0) return;
    utils.msg.error(err.msg || '请求失败');
    reject(err);
  }

  const paramsToFormData = (obj) => {
    const formData = new FormData();
    Object.keys(obj).forEach((key) => {
      if (Array.isArray(obj[key])) {
        obj[key].forEach((item, index) => {
          if (typeof item !== 'object') {
            formData.append(key, item);
          } else {
            Object.keys(item).forEach((arrKey) => {
              if (item[arrKey]) {
                formData.append(`${key}[${index}].${arrKey}`, item[arrKey]);
              }
            })
          }
        });
      } else if (obj[key] != null) {
        formData.append(key, obj[key]);
      }
    });
    return formData;
  }

  const setHeaders = (xhr) => {
    if (!isEmptyObject(head)) {
      Object.keys(head).forEach(key => {
        xhr.setRequestHeader(key, head[key])
      })
    }
  }

  const handleReadyStateChange = (xhr, key, resolve, reject, requestTasks) => {
    return () => {
      if (xhr.readyState === 4) {
        requestTasks.delete(key);
        if (xhr.status === 200) {
          try {
            let res = JSON.parse(xhr.response);
            success(resolve, res);
          } catch (e) {
            error(reject, { status: xhr.status, msg: '解析响应失败' });
          }
        } else {
          error(reject, xhr);
        }
      }
    }
  }

  const createRequest = (key, requestTasks) => {
    const xhr = new XMLHttpRequest();
    xhr.timeout = timeout;
    requestTasks.set(key, xhr);
    return xhr;
  }

  const requestTasks = new Map();

  const request = {
    // 当前上传进度
    nowSchedule: '',

    get: (url, params, key) => {
      let xhr = createRequest(key, requestTasks);
      let defaultUrl = url;
      if (!isEmptyObject(defaultData)) {
        params = { ...params, ...defaultData };
      }
      if (params) {
        const queryString = Object.keys(params).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&');
        defaultUrl += (url.includes('?') ? '&' : '?') + queryString;
      }
      const getUrl = baseUrl + defaultUrl;
      return new Promise((resolve, reject) => {
        xhr.open('GET', getUrl, true);
        setHeaders(xhr);
        xhr.onreadystatechange = handleReadyStateChange(xhr, key, resolve, reject, requestTasks);
        xhr.send();
      })
    },

    post: (url, params, key, type = 'json') => {
      let xhr = createRequest(key, requestTasks);
      const postUrl = baseUrl + url;
      return new Promise((resolve, reject) => {
        xhr.open('POST', postUrl, true);
        setHeaders(xhr);
        if (type === 'json') {
          xhr.setRequestHeader("Content-Type", "application/json");
          xhr.send(JSON.stringify(params));
        } else if (type.toLowerCase() === 'formdata') {
          const formData = paramsToFormData(params);
          xhr.upload.onprogress = (event) => {
            if (event.lengthComputable) {
              request.nowSchedule = `${(event.loaded / event.total) * 100}%`;
            }
          }
          xhr.send(formData);
        } else {
          error(reject, {status: 0, msg: 'post请求中type只支持form和json两种格式'});
        }
        xhr.onreadystatechange = handleReadyStateChange(xhr, key, resolve, reject, requestTasks);
      })
    },
  
    put: (url, params, key) => {
      let xhr = createRequest(key, requestTasks);
      const putUrl = baseUrl + url;
      return new Promise((resolve, reject) => {
        xhr.open('PUT', putUrl, true);
        setHeaders(xhr);
        xhr.setRequestHeader("Content-Type", 'application/json');
        xhr.send(JSON.stringify(params));
        xhr.onreadystatechange = handleReadyStateChange(xhr, key, resolve, reject, requestTasks);
      })
    },

    delete: (url, params, key) => {
      let xhr = createRequest(key, requestTasks);
      if (params) {
        const queryString = Object.keys(params).map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&');
        url += (url.includes('?') ? '&' : '?') + queryString;
      }
      const deleteUrl = baseUrl + url;
      return new Promise((resolve, reject) => {
        xhr.open('DELETE', deleteUrl, true);
        setHeaders(xhr);
        xhr.onreadystatechange = handleReadyStateChange(xhr, key, resolve, reject, requestTasks);
        xhr.send();
      })
    },

    cancel: (key) => {
      let xhr = requestTasks.get(key);
      if (xhr) {
        xhr.abort();
        requestTasks.delete(key);
        console.log(`已取消请求:${key}`);
      }
    },
  }

  return request;
}

const request = createXhrRequest({baseUrl});

for (let i = 0; i <= 10; i++) {
  const key = `/note-published/${i}`;
  request.get('/note-published', null, key).then(res => {
    console.log(res, 'res');
  })
}

// 示例:取消某个请求
request.cancel('/note-published/5');

和axios 一样的调用方式 列:

const regionList = (data) => requestOne.get("/sys/region/list", data);

utils 中的msg内容 (可删除)

 // 提示信息
  msg: {
    // 设置icon 自定义添加
    iconSuccess: '/static/images/success.svg',
    iconError: '/static/images/error.svg',
    iconInfo: '',
    message: document.createElement("p"),
    body: document.getElementsByTagName("body")[0],
    init: () => {
      utils.msg.message.id = "message";
      utils.msg.message.style.top = "-82%";
      utils.msg.message.style.left = "0px";
      utils.msg.message.style.right = "0px";
      utils.msg.message.style.bottom = "0px";
      utils.msg.message.style.zIndex = "9999";
      utils.msg.message.style.margin = "auto";
      utils.msg.message.style.height = "45px";
      utils.msg.message.style.width = "400px";
      utils.msg.message.style.display = "flex";
      utils.msg.message.style.position = "fixed";
      utils.msg.message.style.borderRadius = "6px";
      utils.msg.message.style.alignItems = "center";
      utils.msg.message.style.justifyContent = "center";
    },
    clearMsg: () => {
      if (document.getElementById("message")) {
        document.getElementById("message").remove();
      }
    },
    success: (text) => {
      // 如果有 则给它删除掉 只保留一个
      utils.msg.clearMsg();
      utils.msg.init();
      utils.msg.message.style.color = "rgb(105, 194, 66)";
      utils.msg.message.style.backgroundColor = "rgb(240, 249, 235)";
      utils.msg.message.style.border = "1px solid rgb(225, 243, 217)";
      utils.msg.message.innerHTML = `
      <p
        style="
          display:flex;
          align-items: center;
        ">
        <img
          style="
            display: ${utils.msg.iconSuccess ? 'block' : 'none'};
            width: 24px;
            margin-right: 10px;
          "
          src="${utils.msg.iconSuccess}"
        />
        ${text}
      <p>`;
      utils.msg.body.appendChild(utils.msg.message);
      // N 秒之后如果还有 则给它移除掉
      setTimeout(() => {
        if (document.getElementById("message")) {
          document.getElementById("message").remove();
        }
      }, 5000);
    },
    error: (text) => {
      // 如果有 则给它删除掉 只保留一个
      utils.msg.clearMsg();
      utils.msg.init();
      utils.msg.message.style.color = "rgb(245, 108, 108)";
      utils.msg.message.style.backgroundColor = "rgb(254, 224, 224)";
      utils.msg.message.style.border = "1px solid rgb(252, 211, 211)";
      utils.msg.message.innerHTML = `
      <p
        style="
          display:flex;
          align-items: center;
        ">
          <img
            style="
              display: ${utils.msg.iconError ? 'block' : 'none'};
              width: 24px;
              margin-right: 10px;"
            src="${utils.msg.iconError}"
          />
          ${text}
        <p>`;
      utils.msg.body.appendChild(utils.msg.message);
      // N 秒之后如果还有 则给它移除掉
      setTimeout(() => {
        if (document.getElementById("message")) {
          document.getElementById("message").remove();
        }
      }, 5000);
    },
    info: (text) => {
      // 如果有 则给它删除掉 只保留一个
      utils.msg.clearMsg();
      utils.msg.init();
      utils.msg.message.style.color = "rgb(105, 194, 66)";
      utils.msg.message.style.backgroundColor = "rgb(240, 249, 235)";
      utils.msg.message.style.border = "1px solid rgb(225, 243, 217)";
      utils.msg.message.innerHTML = `
      <p
        style="
          display:flex;
          align-items: center;
        ">
        <img
          style="
            width: 24px;
            margin-right: 10px;
            display: ${utils.msg.iconInfo ? 'block' : 'none'}
          "
          src="${utils.msg.iconInfo}"
        />
        ${text}
      <p>`;
      utils.msg.body.appendChild(utils.msg.message);
      // N 秒之后如果还有 则给它移除掉
      setTimeout(() => {
        if (document.getElementById("message")) {
          document.getElementById("message").remove();
        }
      }, 5000);
    },
  },

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
XMLHttpRequest(XHR)是一种在客户端和服务器之间发送HTTP请求的技术。在这些引用中,我们看到了几个使用XMLHttpRequest的示例。 在第一个示例中,我们创建了一个XMLHttpRequest对象,并使用`open`方法设置请求的方式(GET)和地址以及参数。然后,我们使用`send`方法发送请求,并使用`addEventListener`方法监听`load`事件,以便在响应成功后打印出响应结果。 在第二个示例中,我们同样创建了一个XMLHttpRequest对象,并使用`open`方法设置请求的方式(GET)和URL地址。然后,我们使用`send`方法发送请求,并使用`addEventListener`方法监听`load`事件,以便在响应成功后打印出响应结果。这个示例展示了如何发起带参数的GET请求。 在第三个示例中,我们创建了一个XMLHttpRequest对象,并使用`open`方法设置请求的方式(POST)和URL地址。然后,我们创建了一个URLSearchParams对象,将数据转换成`参数=值`的格式,并使用`setRequestHeader`方法设置对应的`content-type`为`application/x-www-form-urlencoded`。最后,我们使用`send`方法发送请求,并使用`addEventListener`方法监听`load`事件,以便在响应成功后打印出响应结果。这个示例展示了如何发起带请求体的POST请求。 综上所述,这些示例展示了如何使用XMLHttpRequest对象进行封装,包括发起GET请求和POST请求,以及如何处理请求参数和响应结果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [XMLHttpRequest发送网络请求的基本使用,和封装自己的ajax](https://blog.csdn.net/weixin_53312997/article/details/125547811)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值