Ajax搭配Promise的简单封装

前端之家收集整理的这篇文章主要介绍了Ajax搭配Promise的简单封装前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

先说一下平时工作的情况:
日常的工作业务中,与后端数据交互只用了两种形式,GETPOST,写业务代码的时候传的参数都是对象格式{name:'jason',age:27},一般都是这样写:

Http.get('api/userCenter/bookList.json',{
    date: '2010',lang: 'en'
}).then(function(res) {
    console.log(res);
})

Http.post('api/userCenter/login.json',{
    mobile: 13821863666,psd: 123123
}).then(function(res) {
    console.log(this);
})

GET传输时,需要把对应的参数拼接在URL的后面;POST传输时,send的数据格式也主要只用到了以下三种:

  • Content-Type: application/x-www-form-urlencoded,send(data)中的data数据格式为"name=jason&age=27",此时需要序列化参数对象

  • Content-Type: application/json,send(data)中的data数据格式为"{"mobile":13821863666,"psd":123123}",此时需要用JSON.stringify()把参数对象转换成json字符串

  • 使用FormData对象,直接send(FormDataObj)即可,此时不需要设置Content-Type

我就针对以上这些应用场景对ajax做了简单的封装,代码如下:

// http.js

// note:xhr的兼容写法
// function XHR() {
//   if (window.XMLHttpRequest) return new XMLHttpRequest();
//   if (window.ActiveXObject) return new ActiveXObject('Microsoft.XMLHTTP');
//   return 'Not support XMLHttpRequest!';
// }

// 判断是否为纯对象,比如这种格式 {'name': 'jason'} 是纯对象,函数、数组等则不是
function isPlainObject(obj) {
  return Object.prototype.toString.call(obj) === '[object Object]';
}

// 查询字符串中每个参数的名称和值都必须使用 encodeURIComponent() 进行编码,然后才能放到 URL 的末尾;
// 所有名-值对儿都必须由和号 ( & ) 分隔
function addURLParam(url,name,value) {
  url += (url.indexOf('?') == -1 ? '?' : '&');
  url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
  return url;
}

/**
 * Converts an object to x-www-form-urlencoded serialization.
 * http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
 * @param  {Object} obj
 * @return {String}
 */
function serialize(obj) {
  var query = '',value,fullSubName,subName,subValue,innerObj,i;

  for (name in obj) {
    value = obj[name];

    if (value instanceof Array) {
      for (i = 0; i < value.length; ++i) {
        subValue = value[i];
        fullSubName = name + '[' + i + ']';
        innerObj = {};
        innerObj[fullSubName] = subValue;
        query += serialize(innerObj) + '&';
      }
    }
    else if (value instanceof Object) {
      for (subName in value) {
        subValue = value[subName];
        fullSubName = name + '[' + subName + ']';
        innerObj = {};
        innerObj[fullSubName] = subValue;
        query += serialize(innerObj) + '&';
      }
    }
    else if (value !== undefined && value !== null)
      query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
  }

  return query.length ? query.substr(0,query.length - 1) : query;
}

function ajax(type,url,data,contentType) {
  return new Promise(function(resolve,reject) {
    var xhr = new XMLHttpRequest();

    if (type.toUpperCase() === 'GET' && data) {
      for (key in data) {
        if (data.hasOwnProperty(key)) {
          url = addURLParam(url,key,data[key]);
        }
      }
    }

    /** post传输,当传FormData类型的数据时,不需要设置Content-Type
     *  当数据格式为纯对象时
     *  默认设置'Content-Type'为'application/x-www-form-urlencoded',对数据进行序列化
     *  如果'Content-Type'设置为'application/json',数据直接传json字符串
     **/
    if (type.toUpperCase() === 'POST' && isPlainObject(data)) {
      if (!contentType || contentType === 'application/x-www-form-urlencoded') {
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        data = serialize(data);
      } else {
        xhr.setRequestHeader('Content-Type','application/json');
        data = JSON.stringify(data);
      }
    }

    xhr.open(type,true);

    xhr.onload = function() {
      if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
        var res = JSON.parse(xhr.response);
        resolve(res);
      } else {
        reject(xhr.statusText);
      }
    };

    xhr.timeout = 10000;
    xhr.ontimeout = function() {
      reject('链接超时!')
    };
    xhr.onerror = function() {
      reject('网络错误!');
    };
    xhr.onabort = function() {
      reject('请求取消!');
    };

    xhr.send(type.toUpperCase() === 'GET' ? null : data); // 如果不需要通过请求主体发送数据,则必须传入null,因为这个参数对有些浏览器来说是必需的
  });
}

export default {
  get: function(url,data) {
    return ajax('GET',data);
  },post: function(url,contentType) {
    return ajax('POST',contentType);
  }
}

之后就可以在其他文件中使用getpost这两个接口:

import Http form 'http'

Http.get('api/userCenter/bookList.json',psd: 123123
}).then(function(res) {
    console.log(this);
})

get的使用形式是Http.get(url,data)post的使用形式是Http.post(url,contentType),第三个参数contentType可选,当设置了对应的值时,http.js会对传入的参数做不同格式化的处理。

原文链接:https://www.f2er.com/ajax/161284.html

猜你在找的Ajax相关文章