ES5 & ES6精華

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()
// }
相關文章
相關標籤/搜索