原生h5封装ajax全局挂载(可监听连接失败/请求成功/失败/超时)

原生h5封装ajax全局挂载(连接失败/请求成功/失败/超时)

// ajax
/**
 * 业务 http 请求
 * @param uri 接口文档地址, 比如: GET /parkingOrder/{parkingOrderId}/payInfo
 * @param input 入参
 * @param callback 响应
 * @param final 不论成功失败都执行
 */
window.http = function (uri, input,type, callback, final) {
  http.loading.startHttp(uri)//旋转加载图标

  //入参少了input的时候
  if (typeof input === 'function') {
    final = callback
    callback = input
    input = {}
  }
  var res = ''
  var realUri = uri
  baseHTTP({
    uri: realUri,
    input: input,
    type:type,
    success: function (responce) {
      res = responce
    },
    error: function (http) {
      res = {code: http.status, msg: '网络错误 http.status: ' + http.status, http: http}
      alert({msg:realUri+'接口出错,请退出重试', callback: window.closeWindow})
    },
    complete: function () {
      http.loading.completeHttp(uri)
      callback && callback(res, realUri)
    }
  })
}
/**
 * 底层 http 请求
 * @param option 如 defaultOption 所示
 */
function baseHTTP (option) {
  var defaultOption = {
    uri: '',
    input: {},
    id: '',
    type:'GET',
    host: window.config.host,
    success: function (res) {}, // 请求成功
    error: function (err) {}, // 请求错误
    complete: function () {} // 请求完成
  }
  option = Object.assign(defaultOption, option)
  var http = new XMLHttpRequest()
  http.onreadystatechange = function () {
    if (http.readyState === 4) {
      if (http.status === 200) {
        var result = JSON.parse(http.responseText)
        option.success(result)
      } else {
        option.error(http)
      }
      option.complete(http)
    }
  }
  
  var type = option.type?option.type:'GET'//ny 判断get/post  \s匹配任何空白字符  [^\s]匹配任何非空白字符
  var url = option.host + option.uri//id 在上一步已近被替换了,在这应该用不到了
  if (type === 'GET') {
    var getParam = '?'
    option.input && Object.keys(option.input).forEach(function (key) {
      var item = option.input[key]
      if (item && typeof item === 'object') {
        getParam += key + '=' + JSON.stringify(item) + '&'
      } else {
        getParam += key + '=' + (item || '') + '&'
      }
    })
    //将最后一个&结尾字符去掉
    url += getParam.replace(/[&|?]$/, '')
  }
  if(type === 'POST'){
    
  }
  //处理当open之前--->readyState=4 之前发生的错误
  http.onerror = function(){
    // 处理连接级别的错误
    option.error(http)
    return
  };
  console.log(type,url)
  http.open(type, url, true)
  http.setRequestHeader('Content-type', 'application/json')
  localStorage.sessionId && http.setRequestHeader('sessionId', localStorage.sessionId)
  //超过7秒视为超时
  http.timeout = 7000
  http.ontimeout=function(){
    alert({msg: option.uri+'接口'+objs.type+',请退出重试', callback: window.closeWindow})
  }
  http.send(JSON.stringify(option.input))
}

/** 如果请求时间超过 1 秒钟还没响应, 那么自动 loading **/
http.loading = {
  timeout: 1000,
  timeoutList: {},
  startHttp: function (uri) {
    clearTimeout(this.timeoutList[uri]) // TODO 同一个请求在没有响应的时候又发起了, 那么这时有漏洞
    this.timeoutList[uri] = setTimeout(this.show, this.timeout)
  },
  completeHttp: function (uri) {
    //判断是否存在接口超时的情况  如果有就提示,跳出弹框  关闭页面
    clearTimeout(this.timeoutList[uri])
    this.timeoutList[uri] = undefined
    this.hide()
  },
  show: function () {
    if (document.body.className.indexOf('http-loading') > -1) return
    $(document.body).addClass('http-loading')
  },
  hide: function () {
    var isOk = true // 可以隐藏
    var t = this

    //这里用forEach 不好   用some 之类的可能会好(兼容?)
    Object.keys(t.timeoutList).forEach(function (key) {
      var item = t[key]
      if (item !== undefined) {
        isOk = false
      }
    })
    if (!isOk) return
    $(document.body).removeClass('http-loading')
  }
}

页面用法:

http('/goods', {
      example:'测试',
    },'GET', function (res, uri) {
      console.log('打印结果',res)
    })
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_小郑有点困了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值