如何自己封装一个ajax函数
用ajax的局部刷新来给网站提升用户体验我们已经用过很多了,ajax已然成为了前端开发最重要的“工具”之一。
但是,我想应该会有不少人在使用ajax的时候都在依赖于jQuery或者prototype或者其他js库。但现实是,假设某一天一个项目不能引入任何一个js库,只能用原生js写代码,那你怎么办?又或者是一个非常简单的页面,但是要用到ajax,难道就为了下这么一个ajax请求要引用一个jq这么大的js库?我想这是不值得的,所以我们应该学会用原生的js来写ajax,并且把它封装好以便于以后使用。
由于之前使用过jq的ajax而且觉得他使用起来挺舒服的,所以我在封装ajax的时候一方面舍去了很多不常用的参数只留下了最常用的几个功能,另一方面尽量保持它原有的使用风格。
我一共只留了五个参数,他们分别是发送方式(type)、发请求的url(url)、是否为异步请求(async)、发送的参数(data)、传输成功的回调函数(success),函数代码如下:
/* 封装ajax函数 * @param {string}opt.type http连接的方式,包括POST和GET两种方式,默认使用GET * @param {string}opt.url 发送请求的url * @param {boolean}opt.async 是否为异步请求,true为异步的,false为同步的 * @param {object}opt.data 发送的参数,格式为对象类型 * @param {function}opt.success ajax发送并接收成功调用的回调函数 */
function ajax(opt) {
opt = opt || {};
var type = opt.type || 'GET';
type = type.toUpperCase() || 'GET';
var url = opt.url || '';
var async = opt.async || true;
var data = opt.data || null;
var success = opt.success || function () {};
var xmlHttp = null;
if (XMLHttpRequest) {
xmlHttp = new XMLHttpRequest();
}
else {
xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
}
var params = [];
for (var key in data){
params.push(key + '=' + data[key]);
}
var dataStr = params.join('&');
if (type === 'POST') {
xmlHttp.open(type, url, async);
xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
xmlHttp.send(dataStr);
}
else {
xmlHttp.open(type, url + '?' + dataStr, async);
xmlHttp.send(null);
}
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
success(xmlHttp.responseText);
}
};
}
以对象的形式做函数的参数还是比较灵活的,不用拘泥于参数个数的问题。但这容易出现一个问题,就是使用参数的时候很有可能参数没给却在函数内部使用了,比如在调用函数时忘了写success回调函数,而定义的时候却用到了他,这就会报错了,因为success是undefined了。所以为了避免这种情况我觉得最好在封装函数的时候尽量给每一个参数一个默认值,如果调用的时候未给出某个参数那么他就使用默认值代替,这样就不会出现上述情况了。
接下来下面是创建XMLHttpRequest对象,写了两种创建方式是为了兼容IE才有的写法,旧版本的IE浏览器不支持XMLHttpRequest构造函数,IE有他自己独特的构造函数来支持ajax那就是ActiveXObject构造函数。
创建好了XMLHttpRequest对象,接下来写的是对发送参数data的转换,在使用ajax函数的时候data也用json的数据格式会有一种亲切感,因为大部分ajax传输的时候返回数据都使用json格式,所以发送的时候也使用json格式显得很友好。这里需要将{a: b, c: d}的格式转换为a=b&c=d的格式。
然后是对"POST"和"GET"两种不同的发送方式做处理。GET方法比较简单,直接把整理好的数据接在open方法的url参数的后面就行了(要记得在url后面加上"?"),send方法也不用带参数了,因为参数已经在url后面带着发过去了,所以send方法的参数直接给个null;POST方法这里有个坑,如果不注意可能会很烦恼为什么会得不到想要的结果,那就是需要设定Content-Type头信息,模拟HTTP的POST方法发送一个表单,这样服务器才会知道如何处理上传的内容。send方法中参数的提交格式和GET方法中url的写法一样,也是a=b&c=d格式。注意open方法必须放在设定头信息的前面,否则也会报错。async参数可以是true也可以是false,true代表使用异步方式调用,false代表使用同步方式调用,理所当然使用ajax是一定用异步的,这里只是提供一个选择,而且他的默认值也是true。
最后需要注册一个onreadystatechange事件,当XMLHttpRequest对象的readyState属性等于4了(代表收到完整的服务器响应了),同时status属性等于200(代表服务器响应的状态值为OK,状态正常)就可以判定这次ajax从发送过程到响应过程全程传输成功了,我们可以对返回的数据做一些处理,把要处理的代码写在success函数中,ajax成功就会调用之。
// 使用示例 ajax({ method: 'POST', url: 'test.php', data: { name1: 'value1', name2: 'value2' }, success: function (response) { // codes here } });
这个ajax函数很简单代码量也很少,已经基本满足我的日常使用需求了,以后使用也不用依赖js库或者每次写一遍了。如果以后还有更多其他功能要使用,再往里面加。