模仿jQuery封装Ajax
前面的文章,我们已经了解了原生的ajax的请求,但封装的过程仍然发现,参数的传递有很大的的不足之处,现在模仿jQuery的方式,使用对象的形式进行传递参数,并对ajax进行更加完善的封装,目的在与理解jQuery中的底层代码是如何是实现ajax的请求;
首先,设定一个默认对象,用于引入默认参数,再通过遍历的方式,使传递的参数替换掉默认的值;
function ajax(obj){
//设置默认值,若不传值则不会报错
var defaults={
type: 'get',
data: {},
url:'#',
dataType:'text',
async:true,
success:function(){
console.log(data);
}
}
//循环遍历,传值替换默认值
for(var key in obj){
defaults[key]=obj[key];
}
var xhr = null;
if(window.XMLHttpRequest){
xhr =new XMLHttpRequest;
} else {
xhr = new ActiveXObject('Microsofr.XMLHTTP');
}
xhr.open(defaults.type, defaults.url, defaults.async);
xhr.send();
xhr.onreadystatechange=function(){
if(xhr.readystate==4){
if(xhr.status==200){
var data =xhr.responseText;
defaults.success(data);
}
}
}
}
1.data数据处理
我们设置的data默认为一个对象参数,而实际发布的为字符串形式的参数,首先将data进行处理:
将传递得字符串进行拼接:
function ajax(obj){
...省略
var xhr = null;
if(window.XMLHttpRequest){
xhr =new XMLHttpRequest;
} else {
xhr = new ActiveXObject('Microsofr.XMLHTTP');
}
var param='';
for(var attr in obj.data){
// 拼接参数,但最后一个参数多了一个“&”,得删除
param+=attr+"="+obj.data[attr]+'$';
}
if(param){ //若param不为空,则含有多一个&
param=param.substring(0, param.length-1);
}
...省略
}
2.处理请求得方式:
function ajax(obj){
...省略
var param='';
for(var attr in defaults.data){
// 拼接参数,但最后一个参数多了一个“&”,得删除
param+=attr+"="+defaults.data[attr]+'$';
}
if(param){ //若param不为空,则含有多一个&
param=param.substring(0, param.length-1);
}
if(defaults.type=="get"){
//使用encodeURI防止传入中文乱码
defaults.url+='?'+encodeURI(param);
}
xhr.open(defaults.type, defaults.url, defaults.async);
var data = null; //引入data得目的是为了处理post与get传递参数方式不同;
if(defaults.type=="post"){
data=param;
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
xhr.send(data);
...省略
}
3.处理返回数据类型:
若为JSON,使用JSON.parse解析成JS对象;
因为目前不太使用XML格式数据,此处不再进行封装;
function ajax(obj){
...省略
xhr.send(data);
xhr.onreadystatechange=function(){
if(xhr.readystate==4){
if(xhr.status==200){
var data =xhr.responseText;
if(defaults.dataType=="json"){
data=JSON.parse(data);
}
defaults.success(data);
}
}
}
}
4.补充,解决同步的情况:
若请求为同步,则不会执行回调函数
function ajax(obj){
...省略
xhr.send(data);
//判断是否为同步
if(!defaults.async){
// 处理JSON格式数据
if(defaults.datatype=="json"){
return JSON.parse(xhr.responseText);
} else {
return xhr.responseText;
}
}
xhr.onreadystatechange=function(){
...省略
}
}
5.总结:
封装成了一个与jQuery中Ajax底层代码相似的,完整代码如下:
function ajax(obj){
// 默认参数
var defaults = {
type : 'get',
data : {},
url : '#',
dataType : 'text',
async : true,
success : function(data){console.log(data)}
}
// 处理形参,传递参数的时候就覆盖默认参数,不传递就使用默认参数
for(var key in obj){
defaults[key] = obj[key];
}
// 1、创建XMLHttpRequest对象
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
// 把对象形式的参数转化为字符串形式的参数
/*
{username:'zhangsan','password':123}
转换为
username=zhangsan&password=123
*/
var param = '';
for(var attr in defaults.data){
param += attr + '=' + defaults.data[attr] + '&';
}
if(param){
param = param.substring(0,param.length - 1);
}
// 处理get请求参数并且处理中文乱码问题
if(defaults.type == 'get'){
defaults.url += '?' + encodeURI(param);
}
// 2、准备发送(设置发送的参数)
xhr.open(defaults.type,defaults.url,defaults.async);
// 处理post请求参数并且设置请求头信息(必须设置)
var data = null;
if(defaults.type == 'post'){
data = param;
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
// 3、执行发送动作
xhr.send(data);
// 处理同步请求,不会调用回调函数
if(!defaults.async){
if(defaults.dataType == 'json'){
return JSON.parse(xhr.responseText);
}else{
return xhr.responseText;
}
}
// 4、指定回调函数(处理服务器响应数据)
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status == 200){
var data = xhr.responseText;
if(defaults.dataType == 'json'){
// data = eval("("+ data +")");
data = JSON.parse(data);
}
defaults.success(data);
}
}
}
}
测试及使用部分不在叙述,使用与$.ajax()相似,调用为ajax();
感兴趣可以使用之前的文章简单封装一个Ajax中的数据进行测试验证