ES5面向對象編程:ajax
request.js: 一個文件一個模塊 function Service() { this.request = function(opts) { this.opts = Object.assign({}, Service.DEFAULTS, opts) if (window.aladdin && aladdin.http && aladdin.http.request) { return this._aladdinRequest() } else if (window.$ && $.ajax) { return this._ajaxRequest() } else { // 原生請求 return this._xhrRequest() } } } Service.DEFAULTS = { url: '', method: 'GET', contentType: 'application/x-www-form-urlencoded;charset=utf-8', dataType: 'json', // 期待返回數據類型 timeout: 15, // 請求超時設置 data: {}, errorCallback: null, // 統一失敗回調 successCallback: null // 統一成功回調 } // aladdin request Service.prototype._aladdinRequest = function () { console.log('請求工具-->', 'aladdin'); const config = { url: this.opts.url, method: this.opts.method, headers: { 'Content-Type': this.opts.contentType }, timeout: this.opts.timeout, xhrFields: { withCredentials: true } } if (config.method.toUpperCase() === 'POST') { config.body = this.opts.data } else { config.qs = this.opts.data } return new Promise(function(resolve, reject) { aladdin.http.request(config, function (error, res) { if (error) { // 調用失敗 // aladdin.toast.show({ // message: '系統異常,請稍後再試!' // }) reject('系統異常,請稍後再試!') return } if (res.status === 200) { isJsonStr(res.body) ? resolve(JSON.parse(res.body)) : resolve(res.body) // res.body 響應原始內容 } else { reject(res.status + res.statusText) // 響應狀態碼 + 狀態碼對應的文本(如 200 -- OK) } }) }) } // ajax request Service.prototype._ajaxRequest = function () { console.log('請求工具-->', '$.ajax'); let config = { url: this.opts.url, type: this.opts.method, data: this.opts.data, // get請求時,會自動序列化參數後添加到url末尾 headers: { 'Content-Type': this.opts.contentType }, dataType: this.opts.dataType, timeout: this.opts.timeout, xhrFields: { withCredentials: true } } return new Promise(function(resolve, reject) { // when request succeeds config.success = function(data, status, xhr) { if (xhr.status === 200) { resolve(data) // data: 響應原始內容 } else { reject(xhr.status + xhr.statusText) // 響應狀態碼 + 狀態碼對應的文本(如 200 -- OK) } } // if there is an error (timeout, parse error, or status code not in HTTP 2xx) config.error = function(xhr, textStatus) { reject('系統異常,請稍後再試!') } $.ajax(config) }) } // XMLHttpRequest request Service.prototype._xhrRequest = function () { console.log('請求工具-->', 'XMLHttpRequest'); let url = this.opts.url const method = this.opts.method.toUpperCase() const data = this.opts.data // 若是是 GET 請求,須要處理 data 裏的數據而且以必定的規則拼接到 url 後 if (method === 'GET') { var formData = [] for(key in this.opts.data) { formData.push(''.concat(key, '=', this.opts.data[key])) } let params = formData.join('&') if (params.length > 0) { url += url.indexOf('?') >= 0 ? ''.concat('&', params) : ''.concat('?', params) } } let xhr = null if (window.XMLHttpRequest) { xhr = new XMLHttpRequest() } else if (window.ActiveXObject) { xhr=new ActiveXObject("Microsoft.XMLHTTP") } xhr.timeout = this.opts.timeout // xhr.responseType = 'json' // 指定類型與服務器返回值類型如果兼容的,則按指定類型返回,若不兼容則返回null xhr.withCredentials = true xhr.open(method, url, true) xhr.setRequestHeader('Content-Type', this.opts.contentType) return new Promise(function(resolve, reject) { xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { isJsonStr(xhr.response) ? resolve(JSON.parse(xhr.response)) : resolve(xhr.response) // xhr.response,整個響應體 } else { reject(xhr.status + xhr.statusTxt) // 響應狀態碼 + 狀態碼對應的文本(如 200 -- OK) } } } xhr.onerror = function(e) { reject('系統異常,請稍後再試!') } xhr.ontimeout = function(e) { } xhr.send(method === 'POST' ? data : null) }) } // 檢查是否JSON文本 const isJsonStr = function(value){ try { eval('('+value+')') return true } catch(er){ return false } } var req = new Service() // var p = req.request({ // url: '/hget', // method: 'GET', // data: { name: 'zhangsan' } // }) var p = req.request({ url: '/hput', method: 'PUT', data: { name: 'zhangsan' } }) // var p = req.request({ // url: '/hpost', // method: 'POST', // data: { name: 'zhangsan' } // }) p.then(res => console.log('resolved', res)).catch(err => console.log('rejected', err)) // module.exports = { // service: new Service() // }