封裝一個原生js的ajax請求,支援IE9CORS跨域請求
前言
關於純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部落格文章底部和右側廣告記得有空幫忙點選一下哦~~