前端手写系列-手写原生ajax请求

发送原生ajax请求分为以下几个步骤

  1. 实例化XMLHttpRequest对象获取xhr对象
  2. 调用xhr对象的open方法。open方法接受3个参数,请求方法(get或者post), 请求url(get请求的内容会拼接在url上面), 请求是否异步(99%的情况下我们会选择异步);
  3. 调用xhr对象的send方法,其中get请求无需传参,对于post请求需要传参
  4. 监听xhr对象onreadystatechange回调函数,如果readyState为4(表示响应内容解析完成,可以在客户端调用)。然后根据xhr对象上的status来判断当前请求是成功还是失败。status对应的是http code
const GET = "GET";
const POST = "POST";
const noop = () => {};

class Ajax {
  constructor() {
    // IE6以下不支持XMLHttpRequest,需要实例化ActiveXObject对象
    // 现在基本没有公司需要考虑IE6以下的版本,所以这里基本可以忽略ActiveXObject这种情况
    this.xhr = XMLHttpRequest
      ? new XMLHttpRequest()
      : new ActiveXObject("Microsoft.XMLHTTP");
  }

  /**
   * 格式化数据
   * {name: 'aa', age: 10} => name=aa&age=10
   */
  formatData(data = {}) {
    const arr = [];
    for (let key in data) {
      arr.push(encodeURIComponent(key) + "=" + data[key]);
    }
    return arr.join("&");
  }

  /**
   * 发送请求,分为GET请求和POST请求
   */
  request(options = {}) {
    const self = this;
    this.data = this.formatData(options.data);
    this.type = (options.type || GET).toUpperCase();
    this.url = options.url;
    if (!this.url) {
      throw new Error("ajax url is required.");
    }
    this.success = options.success || noop;
    this.error = options.error || noop;

    if (this.type === GET) {
      this.xhr.open(this.type, this.url + "?" + this.data, true);
      this.xhr.send();
    } else if (this.type === POST) {
      this.xhr.open(this.type, this.url, true);
      this.xhr.setRequestHeader(
        "Content-Type",
        "application/x-www-form-urlencoded"
      );
      this.xhr.send(this.data);
    }
    this.xhr.onreadystatechange = function () {
      if (self.xhr.readyState === 4) {
        // 200-请求成功
        // 204-请求成功,但是没有资源返回
        // 206-请求成功,部分返回
        if ([200, 204, 206].indexOf(self.xhr.status) > -1) {
          const result = self.xhr.responseText;
          typeof self.success === "function" &&
            self.success.call(self.xhr, result);
        } else {
          const error = self.xhr.responseText;
          typeof self.error === "function" && self.error.call(self.xhr, error);
        }
      }
    };
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值