公告:携程招聘java、前端、测试、产品等,请发简历至374947554@qq.com,帮内推!

封装一个原生js的ajax请求,支持IE9CORS跨域请求

1409次浏览

前言

关于纯js的ajax请求,我之前有文章写过,https://www.haorooms.com/post/js_ajax_chun, 关于CORS跨域资源共享,我也有文章写过,https://www.haorooms.com/post/cors_requestheaders, 但是在IE8和IE9中,cors跨域是无效的。针对这个,其实IE有个另类的CORS请求,仅仅在IE8和IE9中存在,IE10就废弃了,假如你要兼容IE8和IE9,那么这个属性就用到了。

IE8和IE9的 XDomainRequest

在IE中存在一个已经废弃了的属性XDomainRequest,这个属性在IE8和IE9中运行良好。

方法如下:

if(window.XDomainRequest){
  var xdr = new XDomainRequest();

  xdr.open("get", "http://www.haorooms.com/api/method");

  xdr.onprogress = function () {
    //Progress
  };

  xdr.ontimeout = function () { 
    //Timeout
  };

  xdr.onerror = function () { 
    //Error Occurred
  };

  xdr.onload = function() {
    //success(xdr.responseText);
  }

  setTimeout(function () {
    xdr.send();
  }, 0);
}

文档请看:https://developer.mozilla.org/en-US/docs/Web/API/XDomainRequest

原生js的ajax请求,

// 因为要兼容IE8和IE9,这里就不用Promise了,因为用了之后babel打包瞬间变大
// 创建请求对象
function CreateRequest() {
  try {
    if (window.XMLHttpRequest) {
      return new XMLHttpRequest()
    } else if (window.ActiveXObject) {
      return new ActiveXObject('Microsoft.XMLHTTP')
    }
  } catch (e) {
    console.log(e)
  }
  return null
}
// IE9及IE8不支持CORS跨域请求,针对IE9和IE8做请求兼容
function IE89Request(request) {
  if (IsEmptyObject(request)) {
    return
  }
  request.Method = request.Method == undefined ? 'GET' : request.Method
  if (StringIsNullOrEmpty(request.Url)) {
    return
  }
  if (window.XDomainRequest) {
    var xdr = new XDomainRequest()
    xdr.open(request.Method, request.Url)
    xdr.onerror = function () {
      if (request.ErrorCallback != undefined && typeof (request.ErrorCallback) == 'function') {
        request.ErrorCallback('XDomainRequest error')
      }
    }
    xdr.onload = function() {
      // console.log(xdr.responseText)
      try {
        if (request.SuccessCallback != undefined && typeof (request.SuccessCallback) == 'function') {
          var json = JSON.parse(xdr.responseText)
          request.SuccessCallback(json, xdr)
        }
      } catch (e) {
        // console.log(e, '进入请求error')
        if (request.ErrorCallback != undefined && typeof (request.ErrorCallback) == 'function') {
          request.ErrorCallback(e)
        }
      }
    }
    setTimeout(function () {
      xdr.send(request.Data)
      return xdr
    }, 0)
  }
}

// 数据请求函数封装
function Request (request) {
  if (IsEmptyObject(request)) {
    return
  }
  // 初始化请求属性
  request.Method = request.Method == undefined ? 'GET' : request.Method
  if (StringIsNullOrEmpty(request.Url)) {
    return
  }
  // 默认异步请求
  request.Async = request.Async == undefined ? true : request.Async
  request.Headers = request.Headers == undefined ? {} : request.Headers
  request.DataType = request.DataType == undefined ? 'json' : request.DataType
  request.ContentType = request.ContentType == undefined ? 'application/x-www-form-urlencoded' : request.ContentType
  request.Data = request.Data == undefined ? '' : request.Data
  var xmlHttp = null
  // 创建请求
  xmlHttp = CreateRequest()
  if (xmlHttp == null) {
    return
  }
  // 打开请求
  xmlHttp.open(request.Method, GetUrl(request.Url), request.Async)
  // 设置请求头信息
  xmlHttp.setRequestHeader('Accept', request.DataType)
  xmlHttp.setRequestHeader('Content-Type', request.ContentType)
  for (var key in request.Headers) {
    xmlHttp.setRequestHeader(key, request.Headers[key])
  }
  // 处理请求响应返回
  xmlHttp.onreadystatechange = function () {
    // readyState属性用来表示请求的状态,有5个可取值,分别是:
    // “0”:表示未初始化,即对象已经建立,但是尚未初始化(尚未调用open()方法);
    // “1”:表示正在加载,此时对象已建立,尚未调用send()方法;
    // “2”:表示请求已发送,即send()方法已调用;
    // “3”:表示请求处理中;
    // “4”:表示请求已完成,即数据接收完毕。
    if (xmlHttp.readyState == 4) {
      if (xmlHttp.status == 200) {
        if (request.SuccessCallback != undefined && typeof (request.SuccessCallback) == 'function') {
          var data
          if (request.DataType == 'json') {
            data = JSON.parse(xmlHttp.responseText)
          } else if (request.DataType == 'xml') {
            data = xmlHttp.responseXML
          } else {
            data = xmlHttp.responseText
          }
          request.SuccessCallback(data, xmlHttp)
        }
      } else {
        if (request.ErrorCallback != undefined && typeof (request.ErrorCallback) == 'function') {
          request.ErrorCallback(xmlHttp)
        } else {
          if (StringIsNullOrEmpty(xmlHttp.responseText)) {
            alert(xmlHttp.status + ':' + xmlHttp.statusText)
          } else {
            alert(xmlHttp.responseText)
          }
        }
      }
    }
  }
  // 发送请求
  xmlHttp.send(request.Data)
  return xmlHttp
}

// POST数据请求
function PostRequest (url, data, successCallback, errorCallback, asyncs) {
  var request = {}
  var xmlHttp = null
  request.Url = url
  request.Method = 'POST'
  request.Async = asyncs
  request.ContentType = 'application/json; charset=utf-8'
  request.Data = JSON.stringify(data)
  request.SuccessCallback = function (a, b) {
    request.IsCallback = true
    successCallback && successCallback(a, b)
  }
  request.ErrorCallback = function (a) {
    request.IsErrorCallback = true
    errorCallback && errorCallback(a)
  }
  if (IEVersion() == 8 || IEVersion() == 9) {
    xmlHttp = IE89Request(request)
  } else {
    xmlHttp = Request(request)
  }
  return xmlHttp
}

请求示例封装

export function api_haoroomsData(data, successCallback, errorCallback) {
  return PostRequest(baseUrl + 'haorooms/haoroomsAjaxtest', data, successCallback, errorCallback)
}

调用

let params = {name:'haorooms',value:'ajaxTest'}
api_haoroomsData(params, function(res){
 // 请求结果
}, funcrion(error){
// 错误结果
})

备注

上面封装中用到了一些方法,例如IEVersion(),判断IE版本,IsEmptyObject判断是否是空对象,StringIsNullOrEmpty空字符串

这里共享一下吧:

    // IE浏览器版本判断
    export function IEVersion() {
      var userAgent = navigator.userAgent // 取得浏览器的userAgent字符串
      var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1 // 判断是否IE<11浏览器
      var isEdge = userAgent.indexOf('Edge') > -1 && !isIE // 判断是否IE的Edge浏览器
      var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1
      if (isIE) {
        var reIE = new RegExp('MSIE (\\d+\\.\\d+);')
        reIE.test(userAgent)
        var fIEVersion = parseFloat(RegExp['$1'])
        if (fIEVersion == 7) {
          return 7
        } else if (fIEVersion == 8) {
          return 8
        } else if (fIEVersion == 9) {
          return 9
        } else if (fIEVersion == 10) {
          return 10
        } else {
          return 6// IE版本<=7
        }
      } else if (isEdge) {
        return 'edge'// edge
      } else if (isIE11) {
        return 11 // IE11
      } else {
        return -1// 不是ie浏览器
      }
    }

// 是否空对象
export function IsEmptyObject (obj) {
  if (obj === null || obj === undefined) {
    return true
  }
  if (typeof (obj) == 'object' && obj.length > 0) {
    return false
  }
  if (typeof (obj) == 'object') {
    var blExists = false
    for (var key in obj) {
      blExists = true
      break
    }
    return !blExists
  }
  return false
}

// 字符串去掉空格
export function StringTrim (str) {
  return (str === undefined || str === null) ? '' : str.replace(/(^\s*)|(\s*$)/g, '').replace(/(^ *)|( *$)/g, '')
}

// 字符串是否为空
export function StringIsNullOrEmpty(value) {
  return (value === null || value === undefined) || StringTrim(value.toString()) == ''
}

就到这里,haorooms博客文章底部和右侧广告记得有空帮忙点击一下哦~~

Tags: jsajax

相关文章: