Ajax的封装

Ajax的封装

  • 设计模式: 为了解决特定问题而给出的简洁优化的解决方案
  • 懒惰模式: 多种方案选择一种的方式
  • 例子: 创建 ajax 对象
    • 四种方式
    • 封装的时候要判断
    • 再找个页面你创建两次的时候
      • 第一次要跑断到第四个
      • 第二次还是要判断到第四个
  • 懒惰模式, 第一次的时候, 判断到第四个, 从第二次开始, 不再进行判断

封装ajax对象

  • 封装一个函数,创建xhr对象
    • 不需要参数
    • 返回值就是一个可以在浏览器使用的xhr对象
  • 封装过程
    • 把每一种创建方式写成一个函数
      • 一次去调用这个函数
      • 如果不报错,表示这个方法可以使用
      • 如果a函数可以使用,表示a函数里面的代码在当前浏览器可以正常使用
      • 我把cerXhr重新赋值,赋值为0
      • 从此以后,当你再调用creXhr的时候,其实就是在调用a函数
    • 把四个函数放在一个数组里面
      • 循环遍历这个数组
      • 循环的尝试
    • 准备一个开关
      • 判断数组里面是不是有能执行的
      • 开始的时候是false
      • 一旦有一个可以使用 变量赋值为true
creXhr 创建 ajax 对象
@return { OBJECT } 当前浏览器使用的 ajax 对象

function creXhr() {
  var xhr = null;
  // 准备一个变量
  var flag = false
  // 根据各种判断, 来给 xhr 赋值
  var arr = [
    function () { return new XMLHttpRequest() },
    function () { return new ActiveXObject('Microsoft.XMLHTTP') },
    function () { return new ActiveXObject('Msxml.XMLHTTP') },
    function () { return new ActiveXObject('Msxml2.XMLHTTP') }
  ]
  // arr[i] 是里面的每一个函数
  for (let i = 0; i < arr.length; i++) {
    try {
      xhr = arr[i]()
  // 这里的代码可以执行, 表示 arr[i] 函数里面写的代码就是当前浏览器用的
      creXhr = arr[i]
      flag = true
      break
    } catch (e) {}
  }
   // 判断 flag
   // 如果式 false, 表示数组里面的每一个都不能用
  if (!flag) {
    xhr = '您的浏览器不支持 ajax, 请更换浏览器重试'
    throw new Error(xhr)
  }
  // 返回 xhr
  return xhr
}

封装ajax操作

  • 哪些作为参数使用
    • 请求方式
      • type:默认值GET
    • 请求地址
      • URL:必填
    • 是否异步
      • async:默认值 true
    • 是否执行JSON.parse()
      • dataType:默认是’string’,表示不解析,‘json’
    • 传递给后端的数据
      • data:‘a=100&b=200’ || { a: 100, b: 200 }
  • 确定一下传递参数的方式
    • function ajax(){}
    • ajax(’./xxx/php’,null,null,‘json’,‘a=100’)
    • ajax({type:‘GET’})
    • 对象的方式来传递参数

开始封装

  • 参数验证:你传递的是不是符合规则
    • 1-1url 验证, 必填
    • 1-2. type 验证, 可以不传递, 可以是 GET, 可以是 POST, 大小写无所谓,其他的都不行
    • 1-3. async 验证, 可以不传递, 可以是 true 可以是 false,
      • 要么不传递,要么就是boolean
    • 1-4.dataType 验证, 可以不传递, 要么是 ‘string’ 要么是 ‘json’
    • 1-5. data 验证, 可以不传递, 可以是字符串类型, 可以是 object 类型
    • 1-6. success 和 error 验证, 可以不传递, 要么就得是函数
  • 设置一套默认值
    • 后期的请求发送都是使用默认值发送
    • 设置默认值的时候, 把 data 单独操作一下
    • 判断如果是一个对象, 我把他还原成 字符串的形式再使用
  • 发送请求
    • 按照 _default 里面的内容发送请求
  • 回调函数
    • 目前发送 ajax 只能把结果再控制台打印
    • 我们就把想在请求结束后做的事情包装成一个 盒子, 传递给 ajax 里面
    • 让他在请求成功的时候, 给我把盒子执行掉
function ajax(options = {}) {
      // options = {} 目的: 为了保证你的 options 是一个对象
      // 我执行 options.xxx 的时候不会报错
      // options.success 和 error 式两个函数数据类型或者没传递

      // 1. 参数验证
      // 1-1. 验证 url
      if (!options.url) {
        throw new Error('url 为必填选项')
      }

      // 1-2. 验证 type
      if (!(options.type == undefined || options.type.toUpperCase() === 'GET' || options.type.toUpperCase() === 'POST')) {
        throw new Error('目前只接收 GET 或者 POST 请求方式, 请期待更新')
      }

      // 1-3. 验证 async
      if (!(options.async == undefined || typeof options.async === 'boolean')) {
        throw new Error('async 需要一个 Boolean 数据类型')
      }

      // 1-4. 验证 dataType
      if (!(options.dataType == undefined || options.dataType === 'string' || options.dataType === 'json')) {
        throw new Error('目前只支持 string 和 json 格式解析, 请期待更新')
      }

      // 1-5. 验证 data
      if (!(options.data == undefined || typeof options.data === 'string' || Object.prototype.toString.call(options.data) === '[object Object]')) {
        throw new Error('data 参数只支持 string 和 object 数据类型')
      }

      // 1-6. 验证 success 和 error
      if (!(options.success == undefined || typeof options.success === 'function')) {
        throw new Error('success 传递一个函数类型')
      }

      if (!(options.error == undefined || typeof options.error === 'function')) {
        throw new Error('error 传递一个函数类型')
      }

      // 代码来到这里, 说明 options.success 和 error 肯定是一个 undefined 或者 function

      // 2. 设置一套默认值
      var _default = {
        url: options.url,
        // 代码能来到这里, 说名 undefined  get  post
        type: options.type || 'GET',
        // 代码能来到这里, 说明 undefined true false
        // 三元表达式, 如果你式个 布尔值, 那么就用你的, 否则用 true
        async: typeof options.async === 'boolean' ? options.async : true,
        // 代码能来到这里, 说明 undefined 'string' 'json'
        dataType: options.dataType || 'string',
        // 代码能来到这里, 说明 undefined '' {}
        data: options.data || '',
        // 如果你传递了是一个 function, 就用你传递的, 否则我就给一个默认函数
        success: options.success || function () {},
        error: options.error || function () {}
      }

      // 到这里, _default.success 和 error 肯定式一个函数

      // 2-2. 单独调整一下 data
      // 能来到这里, _default.data 只能是 '' {}
      if (typeof _default.data === 'object') {
        // 准备一个空字符串
        var str = ''
        for (var key in _default.data) {
          str += key + '=' + _default.data[key] + '&'
        }
        // 拼接完毕以后, 把最后一位去掉, 从新赋值给 _default.data
        _default.data = str.slice(0, -1)
      }


      // 3. 发送请求
      var xhr = creXhr()

      // 3-1. 请求地址, 如果是 get 请求 url + '?' + data
      //               如果式 post 请求 url
      // 判断, 如果是 get 请求, 那么我把 _default.url 修改一下
      if (_default.type.toUpperCase() === 'GET' && _default.data) {
        _default.url += '?' + _default.data
      }
      xhr.open(_default.type, _default.url, _default.async)
      xhr.onreadystatechange = function () {
        if (xhr.status >= 200 && xhr.status < 300 && xhr.readyState === 4) {
          // 3-3. 判断 dataType 如果式 json 要解析
          if (_default.dataType === 'json') {
            // 成功, 不需要打印
            // 调用 _default.success()
            var res = JSON.parse(xhr.responseText)
            // 要吗调用的式你传递进来的函数, 要吗调用的式默认函数
            // 调用的如果式默认函数, 那么就相当于什么都没执行
            // 如果调用的式你传递进来的函数, 那么你在函数里面写什么就执行什么
            _default.success(res)
          } else if (_default.dataType === 'string') {
            _default.success(xhr.responseText)
          }
        }

        if (xhr.readyState === 4 && xhr.status >= 400) {
          _default.error(xhr.status)
        }
      }

      // 3-2. 判断是不是 post 请求
      if (_default.type.toUpperCase() === 'POST') {
        xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')
      }
      xhr.send(_default.data)
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值