使用promise 封装XMLHttpRequest

/*
使用promise 封装XMLHttpRequest
(resove, reject) 对应请求的(then,catch)
 config 请求参数
 data 可选
 url  必须
 method 必须
 timetout 可选默认(3000)
 responseType 可选
 使用时,then先后catch
 */

export default function xhrRequest (config) {
  return new Promise(function dispRequest (resolve, reject) {
    if (!config.url) {
      return reject(createError('请求的URL不存在', config, null))
    }

    if (!config.method) {
      return reject(createError('请求方式不存在', config, null))
    }
    // form data
    var requestData = new FormData()
    var data = config.data
    for (const key in data) {
      requestData.append(key, data[key])
    }
    // var requestData = new FormData(config.data)

    var request = new XMLHttpRequest()

    var URL = config.url
    var method = config.method.toUpperCase()

    request.open(method, URL, true)

    request.timeout = config.timetout || 3000

    // listen for ready state
    request.onreadystatechange = function () {
      if (!request || request.readyState !== 4) {
        return
      }
      if (
        request.status === 0 &&
        !(request.reponseURL && request.reponseURL.indexof('file') === 0)
      ) {
        return
      }

      // 进度
      request.upload.onprogress = function (a, b) {
        console.log(a, b)
      }
      // 浏览器取消
      request.onabort = function () {
        if (!request) {
          return
        }

        reject(createError('请求取消', config, 'ECONNABORTED', request))

        request = null
      }

      // 网络错误
      request.onerror = function () {
        reject(createError('网络错误', config, null, request))

        request = null
      }

      // timeout
      request.ontimeout = function () {
        var timeoutErrorMessage = '请求超时 ' + config.timeout + 'ms exceeded'
        if (config.timeoutErrorMessage) {
          timeoutErrorMessage = config.timeoutErrorMessage
        }
        reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', request))

        request = null
      }
      // request.status 可能的状态码
      // 404
      // 200
      // 500
      const state = request.status
      const stateString = {
        404: '请求的网页不存在!',
        500: '服务不可用!'
      }
      if (state === 404 || state === 500) {
        reject(createError('请求错误,类型:' + stateString[state] + '多次出现请联系管理员', config, null, request))
        request = null
        return
      }

      var responseHeaders =
        'getAllResponseHeaders' in request
          ? parseHeaders(request.getAllResponseHeaders())
          : null

      var responseData = !config.responseType || config.responseType === 'text'
        ? request.responseText
        : request.response

      var response = {
        data: JSON.parse(responseData),
        status: request.status,
        statusText: request.statusText,
        headers: responseHeaders,
        config: config,
        request: request
      }

      settle(resolve, reject, response)
      // Clean up request
      request = null
    }

    if (requestData === undefined) {
      requestData = null
    }
    // Send the request
    request.send(requestData)
  })
}

function settle (resolve, reject, response) {
  var validateStatus = response.config.validateStatus
  if (!validateStatus || validateStatus(response.status)) {
    resolve(response)
  } else {
    reject(
      createError(
        '请求异常,状态码为:' + response.status,
        response.config,
        null,
        response.request,
        response
      )
    )
  }
}

function createError (message, config, code, request, response) {
  var error = { error: message }
  return enhanceError(error, config, code, request, response)
}

function enhanceError (error, config, code, request, response) {
  error.config = config
  if (code) {
    error.code = code
  }

  error.request = request
  error.response = response
  error.isAxiosError = true

  error.toJSON = function () {
    return {
      // Standard
      message: this.message,
      name: this.name,
      // Microsoft
      description: this.description,
      number: this.number,
      // Mozilla
      fileName: this.fileName,
      lineNumber: this.lineNumber,
      columnNumber: this.columnNumber,
      stack: this.stack,
      // Axios
      config: this.config,
      code: this.code
    }
  }
  return error
}

function parseHeaders (headers) {
  var obj = {}
  var arr = headers.split(/[(\r\n)\r\n]+/)
  arr.pop()
  arr.forEach(item => {
    // item = item.concat('"').replace(/: /g, ': "')
    var rp = item.split(':', 2)
    obj[rp[0]] = rp[1].substr(1)
  })

  return obj
}

使用示例

 const config = {
          url: url,
          method: 'post',
          data: { name, password }
        }
        Request(config)
          .then((res) => {
            console.log(res)
            this.$message(res.data ? res.data.msg : '数据异常')
          })
          .catch((err) => {
            console.log(err)

            this.$message(err.error)
          })

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值