从零开始封装一个ajax框架

写这篇文章的初衷:写了5年代码,发现天天的工做都是在像拼积木同样,拼凑着一个又一个功能,可是基本的实现原理可能就那几把刷子,想着想着就干脆整理成一个本身风格的公共库,既然说了,那就干呗~javascript

先把最经常使用的一个方法---ajax入手,发现认真去作一件事情还真的不容易,因此就把这个封装ajax的过程整理成一个博客,供你们参考,小弟也虚心听取各位大佬建议~~~php

框架起步

框架的封装是一个开发者综合能力的一个体现,由于框架的封装不只关系到怎么让使用者更方便的去使用你封装的这个方法,更须要一个开发者从原理上去了解为了实现这种方法所进行的每一步操做,每个方法的有效性,能不能用更精简的语句实现,能不能用更高效的方法实现,或者是为了追求某方面的性能而牺牲某方面的体验等等... 暂时想不到好的名字,暂时把框架命名为fly.jshtml

框架封装的原则

根据jquery的源码,可见我们这个框架的封装通常包括两个原则:java

  • 用匿名函数将脚本包起来jquery

    (function(){
    
     })()
    复制代码
  • 使用命名空间(多级) 为了防止全局变量命名冲突,我们使用多级命名空间来避免和项目变量冲突 因此采用F.T,同时由于我们暂时实现的是工具类库(Util),未来有可能还有UI库,或者其余专门处理String、Object的类库,因此我们来个F.T.Utilgit

    • 框架的别名FLY、F、fly等等
    • 框架的一些信息 好比框架名、版本号、项目地址[github]、做者信息等等

给你们看一下初始代码长成什么样,写好后呢,将我们的FLY挂载到windows上github

(function(FLY) {
    /** * fly.js * 版本: 1.0.0 * fly.js尽可能覆盖开发过程当中的常见的场景,提升开发效率 * 博客: https://blog.csdn.net/qtfying * 掘金: https://juejin.im/user/57deadcd0e3dd90069721916 * QQ: 2811132560 * 邮箱: qtfying@gamil.com */
    F = fly = f = FLY;
    F.T = F.T || {};
    F.T.Util = F.T.Util || {};
    var util = F.T.Util;
})(window.FLY = window.fly || {});
复制代码

测试工具库是否正常引入

既然框架已经起步,就要先测试一下框架是否能用,我们先写一个test函数测试一下能不能正常的使用:ajax

util.test = function () {
    console.log('引入fly.js框架成功');
};
复制代码

而后呢,我们在html界面调用一下,看下可否正常执行便可,固然很完美,我们接着下一步 ~json

new XMLHttpRequest()

属性

一个为向服务器发送请求和解析服务器响应提供了流畅的接口。 ajax是一个老生常谈的问题,可是确定有一部分人只是知道ajax而不知道XMLHttpRequest,亦或者是在框架横行的世代,为了发一个请求而又不得不把jquery而引入了进来,其实ajax是jquery是为了方便你们使用而封装的一个好用而又方便实用的一个著名的超过 XMLHttpRequest本尊的请求工具,在ES6的Fetch请求以前,发送一个完整的请求通常状况下包括5个步骤:windows

  • 建立XMLHttpRequest对象(浏览器兼容性)
  • 注册回调函数
  • 建立请求,指定请求类型、地址、异步/同步
  • 发送请求
  • 异步获取响应数据,并利用js与DOM进行页面局部刷新

实现步骤

//步骤一:建立异步对象
var ajax = new XMLHttpRequest();
//步骤二:设置请求的url参数,参数一是请求的类型,参数二是请求的url,能够带参数,动态的传递参数starName到服务端
ajax.open('get','getStar.php?starName='+name);
//步骤三:发送请求
ajax.send();
//步骤四:注册事件 onreadystatechange 状态改变就会调用
ajax.onreadystatechange = function () {
  //步骤五 若是可以进到这个判断 说明 数据 完美的回来了,而且请求的页面是存在的
   if (ajax.readyState == 4 &&ajax.status==200) {
  console.log(ajax.responseText); // 输入相应的内容
  }
}
复制代码

readyState

里面这个readyState都有哪些含义呢:

  • 0:请求未初始化(尚未调用 open())。
  • 1:请求已经创建,可是尚未发送(尚未调用 send())。
  • 2:请求已发送,正在处理中(一般如今能够从响应中获取内容头)。
  • 3:请求在处理中;一般响应中已有部分数据可用了,可是服务器尚未完成响应的生成。
  • 4:响应已完成;您能够获取并使用服务器的响应了。

status

响应的HTTP 状态。

如 200 表示成功,而 404 表示 "Not Found" 错误。当 readyState 小于 3 的时候读取这一属性会致使一个异常。

statusText

HTTP 状态的说明。

当状态为 200 的时候它是 "OK",当状态为 404 的时候它是 "Not Found"。和 status 属性同样,当 readyState 小于 3 的时候读取这一属性会致使一个异常。

responseText

做为响应主体被返回的文本。

若是 readyState 小于 3,这个属性就是一个空字符串。当 readyState 为 3,这个属性返回目前已经接收的响应部分。若是 readyState 为 4,这个属性保存了完整的响应体。

responseXML

若是响应的内容类型是"text/xml"或"application/xml",这个属性将保存着响应数据的XML DOM文档。

send()

做用:发送请求,参数为发送的请求体,不传请求体的话最好传个null

open()

做用:初始化请求

xhr.open(method,url,async,user,password)

  • method 请求方式,如get,post,put等等
  • url 请求路径,能够是相对路径也能够是绝对
  • async 是否异步请求 传布尔值,默认true
  • user 用户名,可选参数,为受权使用;默认参数为空string.
  • password 密码,可选参数,为受权使用;默认参数为空string.

总是这样写也不是办法啊,写出精神ICU的节奏啊,这时候,简单而又明了的写法出来了:

$.ajax({
    type: "GET",
    url: "getUser",
    data: {id: val},   // 看后台要什么格式的,是字符串仍是对象 JSON.stringify(obj)
    success: function(data){},
    error: function(){},
});
复制代码

封装ajax

$.ajax中的一个对象,包含type、url、data、success、error大大的精简了代码的写法,简单明了 ~ 我们本身手动实现一个ajax方法的话,须要考虑哪些方面呢,结合jquery的源码,而且和原生的XMLHttpRequest()方法对比,根据我们实际开发的经验,一个完整的请求包括:

  • json数据,包括url、type、data、succFn、errorFn
  • 处理data中的参数,即将data对象拼接到url
  • 请求超时的处理
  • get方法和post方法

首先我们先把第2项处理掉,怎么将譬如{name: 'yeyu', age: 18}转化为?name=yeyu&age=18这样的字符串呢:

/** * 将参数转拼接为url连接后的传参 * @returns {{String}} */
util.json2url = function(json) {
  var arr = [];
  for(var name in json) {
    arr.push(name + '=' +json[name]);
  }
  return arr.join('&');
};
复制代码

接下来我就直接把封装好的ajax方法贴出来,供你们参考:

/** * 结合jquery,从新封装ajax * @returns {{responseText}} */
util.ajax = function (json) {
  var timer = null;
  json = json || {};
  if (!json.url) {
    alert('请求url不存在,请从新检查');
    return;
  }
  json.type = json.type || 'get';
  json.time = json.time || 10;
  json.data = json.data || {};
  var _Ajax = new XMLHttpRequest();
  switch (json.type.toLowerCase()) {
    case 'get':
      _Ajax.open('GET', json.url + '?' + util.json2url(json.data), true);
      _Ajax.send();
      break;
    case 'post':
      _Ajax.open('POST', json.url, true);
      _Ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      oAjax.send(util.json2url(json.data));
      break;
  }
  _Ajax.onreadystatechange = function() {
    if (_Ajax.readyState == 4) {
      if (_Ajax.status >= 200 && _Ajax.status < 300 || _Ajax.status == 304) {
        clearTimeout(timer);
        json.succFn && json.succFn(_Ajax.responseText);
      } else {
        clearTimeout(timer);
        json.errFn && json.errFn(_Ajax.status);
      }
    }
  };
  timer = setTimeout(function() {
    alert('请求超时,请从新处理 ~ ');
    _Ajax.onreadystatechange = null;
  }, json.time * 1000);
};
复制代码

到这里我们就实现了一个ajax的方法,而不用由于仅仅使用ajax而将jquery引入到项目中

最后呢,再封装两个方法,一个post,一个get,这样基本上就知足了咱们项目中经常使用的请求

/** * post请求 * @returns {{responseText}} */
util.post = function (jsonData) {
  ajax({
    url: jsonData.url,
    data: jsonData.data,
    succFn: jsonData.succFn,
    errFn: jsonData.errFn,
    type: 'post'
  });
};
复制代码
/** * get请求 * @returns {{responseText}} */
util.get = function (jsonData) {
  util.ajax({
    url: jsonData.url,
    data: jsonData.data,
    succFn: jsonData.succFn,
    errFn: jsonData.errFn,
    type: 'get'
  });
};
复制代码

到这里,完整的ajax请求就结束了~~~

相关文章
相关标签/搜索